mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Merge "Merge ab/12162526 into stage-aosp-rvc-ts-dev" into stage-aosp-rvc-ts-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
b6d3dc86a5
@@ -3,6 +3,8 @@
|
||||
hidl_interface {
|
||||
name: "android.hardware.audio@4.0",
|
||||
root: "android.hardware",
|
||||
// TODO(b/153609531): remove when no longer needed.
|
||||
native_bridge_supported: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
},
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
hidl_interface {
|
||||
name: "android.hardware.audio.common@2.0",
|
||||
root: "android.hardware",
|
||||
// TODO(b/153609531): remove when no longer needed.
|
||||
native_bridge_supported: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
},
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
hidl_interface {
|
||||
name: "android.hardware.audio.common@4.0",
|
||||
root: "android.hardware",
|
||||
// TODO(b/153609531): remove when no longer needed.
|
||||
native_bridge_supported: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
},
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
hidl_interface {
|
||||
name: "android.hardware.audio.effect@2.0",
|
||||
root: "android.hardware",
|
||||
// TODO(b/153609531): remove when no longer needed.
|
||||
native_bridge_supported: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
},
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
hidl_interface {
|
||||
name: "android.hardware.audio.effect@4.0",
|
||||
root: "android.hardware",
|
||||
// TODO(b/153609531): remove when no longer needed.
|
||||
native_bridge_supported: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
},
|
||||
|
||||
@@ -105,6 +105,10 @@ enum EvsEventType : uint32_t {
|
||||
* Master role has become available
|
||||
*/
|
||||
MASTER_RELEASED,
|
||||
/**
|
||||
* Any other erroneous streaming events
|
||||
*/
|
||||
STREAM_ERROR,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -2262,6 +2262,7 @@ TEST_P(EvsHidlTest, CameraStreamExternalBuffering) {
|
||||
|
||||
// Allocate buffers to use
|
||||
hidl_vec<BufferDesc> buffers;
|
||||
buffers.resize(kBuffersToHold);
|
||||
for (auto i = 0; i < kBuffersToHold; ++i) {
|
||||
unsigned pixelsPerLine;
|
||||
buffer_handle_t memHandle = nullptr;
|
||||
|
||||
@@ -15,12 +15,10 @@
|
||||
cc_defaults {
|
||||
name: "vhal_v2_0_defaults",
|
||||
shared_libs: [
|
||||
"libbinder_ndk",
|
||||
"libhidlbase",
|
||||
"liblog",
|
||||
"libutils",
|
||||
"android.hardware.automotive.vehicle@2.0",
|
||||
"carwatchdog_aidl_interface-ndk_platform",
|
||||
],
|
||||
cflags: [
|
||||
"-Wall",
|
||||
@@ -29,6 +27,15 @@ cc_defaults {
|
||||
],
|
||||
}
|
||||
|
||||
cc_defaults {
|
||||
name: "vhal_v2_0_target_defaults",
|
||||
defaults: ["vhal_v2_0_defaults"],
|
||||
shared_libs: [
|
||||
"libbinder_ndk",
|
||||
"carwatchdog_aidl_interface-ndk_platform",
|
||||
],
|
||||
}
|
||||
|
||||
cc_library_headers {
|
||||
name: "vhal_v2_0_common_headers",
|
||||
vendor: true,
|
||||
@@ -39,7 +46,7 @@ cc_library_headers {
|
||||
cc_library {
|
||||
name: "android.hardware.automotive.vehicle@2.0-manager-lib",
|
||||
vendor: true,
|
||||
defaults: ["vhal_v2_0_defaults"],
|
||||
defaults: ["vhal_v2_0_target_defaults"],
|
||||
srcs: [
|
||||
"common/src/Obd2SensorStore.cpp",
|
||||
"common/src/SubscriptionManager.cpp",
|
||||
@@ -61,7 +68,7 @@ cc_library {
|
||||
cc_library_static {
|
||||
name: "android.hardware.automotive.vehicle@2.0-default-impl-lib",
|
||||
vendor: true,
|
||||
defaults: ["vhal_v2_0_defaults"],
|
||||
defaults: ["vhal_v2_0_target_defaults"],
|
||||
srcs: [
|
||||
"impl/vhal_v2_0/CommConn.cpp",
|
||||
"impl/vhal_v2_0/EmulatedVehicleConnector.cpp",
|
||||
@@ -97,16 +104,59 @@ cc_library_static {
|
||||
cc_library_static {
|
||||
name: "android.hardware.automotive.vehicle@2.0-emulated-user-hal-lib",
|
||||
vendor: true,
|
||||
defaults: ["vhal_v2_0_defaults"],
|
||||
defaults: ["vhal_v2_0_target_defaults"],
|
||||
srcs: [
|
||||
"impl/vhal_v2_0/EmulatedUserHal.cpp",
|
||||
],
|
||||
}
|
||||
|
||||
// Vehicle HAL Server reference impl lib
|
||||
cc_library_static {
|
||||
name: "android.hardware.automotive.vehicle@2.0-server-common-lib",
|
||||
vendor: true,
|
||||
host_supported: true,
|
||||
defaults: ["vhal_v2_0_defaults"],
|
||||
local_include_dirs: ["common/include/vhal_v2_0"],
|
||||
export_include_dirs: ["common/include"],
|
||||
srcs: [
|
||||
"common/src/Obd2SensorStore.cpp",
|
||||
"common/src/VehicleObjectPool.cpp",
|
||||
"common/src/VehicleUtils.cpp",
|
||||
],
|
||||
}
|
||||
|
||||
// Vehicle HAL Server default implementation
|
||||
cc_library_static {
|
||||
name: "android.hardware.automotive.vehicle@2.0-server-impl-lib",
|
||||
vendor: true,
|
||||
host_supported: true,
|
||||
defaults: ["vhal_v2_0_defaults"],
|
||||
local_include_dirs: ["common/include/vhal_v2_0"],
|
||||
export_include_dirs: ["impl"],
|
||||
srcs: [
|
||||
"impl/vhal_v2_0/EmulatedUserHal.cpp",
|
||||
"impl/vhal_v2_0/GeneratorHub.cpp",
|
||||
"impl/vhal_v2_0/JsonFakeValueGenerator.cpp",
|
||||
"impl/vhal_v2_0/LinearFakeValueGenerator.cpp",
|
||||
"impl/vhal_v2_0/ProtoMessageConverter.cpp",
|
||||
"impl/vhal_v2_0/VehicleHalServer.cpp",
|
||||
],
|
||||
whole_static_libs: [
|
||||
"android.hardware.automotive.vehicle@2.0-server-common-lib",
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.automotive.vehicle@2.0-libproto-native",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libjsoncpp",
|
||||
],
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "android.hardware.automotive.vehicle@2.0-manager-unit-tests",
|
||||
vendor: true,
|
||||
defaults: ["vhal_v2_0_defaults"],
|
||||
defaults: ["vhal_v2_0_target_defaults"],
|
||||
whole_static_libs: ["android.hardware.automotive.vehicle@2.0-manager-lib"],
|
||||
srcs: [
|
||||
"tests/RecurrentTimer_test.cpp",
|
||||
@@ -126,7 +176,7 @@ cc_test {
|
||||
cc_test {
|
||||
name: "android.hardware.automotive.vehicle@2.0-default-impl-unit-tests",
|
||||
vendor: true,
|
||||
defaults: ["vhal_v2_0_defaults"],
|
||||
defaults: ["vhal_v2_0_target_defaults"],
|
||||
srcs: [
|
||||
"impl/vhal_v2_0/tests/ProtoMessageConverter_test.cpp",
|
||||
],
|
||||
@@ -140,7 +190,7 @@ cc_test {
|
||||
|
||||
cc_binary {
|
||||
name: "android.hardware.automotive.vehicle@2.0-service",
|
||||
defaults: ["vhal_v2_0_defaults"],
|
||||
defaults: ["vhal_v2_0_target_defaults"],
|
||||
vintf_fragments: [
|
||||
"android.hardware.automotive.vehicle@2.0-service.xml",
|
||||
],
|
||||
|
||||
@@ -1036,6 +1036,22 @@ const ConfigDeclaration kVehicleProperties[]{
|
||||
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
|
||||
},
|
||||
},
|
||||
{
|
||||
.config =
|
||||
{
|
||||
.prop = toInt(VehicleProperty::CREATE_USER),
|
||||
.access = VehiclePropertyAccess::READ_WRITE,
|
||||
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
|
||||
},
|
||||
},
|
||||
{
|
||||
.config =
|
||||
{
|
||||
.prop = toInt(VehicleProperty::REMOVE_USER),
|
||||
.access = VehiclePropertyAccess::READ_WRITE,
|
||||
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
|
||||
},
|
||||
},
|
||||
{
|
||||
.config =
|
||||
{
|
||||
|
||||
@@ -30,6 +30,8 @@ namespace impl {
|
||||
|
||||
constexpr int INITIAL_USER_INFO = static_cast<int>(VehicleProperty::INITIAL_USER_INFO);
|
||||
constexpr int SWITCH_USER = static_cast<int>(VehicleProperty::SWITCH_USER);
|
||||
constexpr int CREATE_USER = static_cast<int>(VehicleProperty::CREATE_USER);
|
||||
constexpr int REMOVE_USER = static_cast<int>(VehicleProperty::REMOVE_USER);
|
||||
constexpr int USER_IDENTIFICATION_ASSOCIATION =
|
||||
static_cast<int>(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION);
|
||||
|
||||
@@ -37,6 +39,8 @@ bool EmulatedUserHal::isSupported(int32_t prop) {
|
||||
switch (prop) {
|
||||
case INITIAL_USER_INFO:
|
||||
case SWITCH_USER:
|
||||
case CREATE_USER:
|
||||
case REMOVE_USER:
|
||||
case USER_IDENTIFICATION_ASSOCIATION:
|
||||
return true;
|
||||
default:
|
||||
@@ -53,6 +57,11 @@ android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetP
|
||||
return onSetInitialUserInfoResponse(value);
|
||||
case SWITCH_USER:
|
||||
return onSetSwitchUserResponse(value);
|
||||
case CREATE_USER:
|
||||
return onSetCreateUserResponse(value);
|
||||
case REMOVE_USER:
|
||||
ALOGI("REMOVE_USER is FYI only, nothing to do...");
|
||||
return {};
|
||||
case USER_IDENTIFICATION_ASSOCIATION:
|
||||
return onSetUserIdentificationAssociation(value);
|
||||
default:
|
||||
@@ -62,32 +71,44 @@ android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetP
|
||||
}
|
||||
|
||||
android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onGetProperty(
|
||||
int32_t prop) {
|
||||
ALOGV("onGetProperty(%d)", prop);
|
||||
switch (prop) {
|
||||
const VehiclePropValue& value) {
|
||||
ALOGV("onGetProperty(%s)", toString(value).c_str());
|
||||
switch (value.prop) {
|
||||
case INITIAL_USER_INFO:
|
||||
case SWITCH_USER:
|
||||
ALOGE("onGetProperty(): %d is only supported on SET", prop);
|
||||
case CREATE_USER:
|
||||
case REMOVE_USER:
|
||||
ALOGE("onGetProperty(): %d is only supported on SET", value.prop);
|
||||
return android::base::Error(static_cast<int>(StatusCode::INVALID_ARG))
|
||||
<< "only supported on SET";
|
||||
case USER_IDENTIFICATION_ASSOCIATION:
|
||||
if (mSetUserIdentificationAssociationResponseFromCmd != nullptr) {
|
||||
ALOGI("onGetProperty(%d): returning %s", prop,
|
||||
toString(*mSetUserIdentificationAssociationResponseFromCmd).c_str());
|
||||
auto value = std::unique_ptr<VehiclePropValue>(
|
||||
new VehiclePropValue(*mSetUserIdentificationAssociationResponseFromCmd));
|
||||
return value;
|
||||
}
|
||||
ALOGE("onGetProperty(%d): USER_IDENTIFICATION_ASSOCIATION not set by lshal", prop);
|
||||
return android::base::Error(static_cast<int>(StatusCode::NOT_AVAILABLE))
|
||||
<< "not set by lshal";
|
||||
return onGetUserIdentificationAssociation(value);
|
||||
default:
|
||||
ALOGE("onGetProperty(): %d is not supported", prop);
|
||||
ALOGE("onGetProperty(): %d is not supported", value.prop);
|
||||
return android::base::Error(static_cast<int>(StatusCode::INVALID_ARG))
|
||||
<< "not supported by User HAL";
|
||||
}
|
||||
}
|
||||
|
||||
android::base::Result<std::unique_ptr<VehiclePropValue>>
|
||||
EmulatedUserHal::onGetUserIdentificationAssociation(const VehiclePropValue& value) {
|
||||
if (mSetUserIdentificationAssociationResponseFromCmd != nullptr) {
|
||||
ALOGI("get(USER_IDENTIFICATION_ASSOCIATION): returning %s",
|
||||
toString(*mSetUserIdentificationAssociationResponseFromCmd).c_str());
|
||||
auto newValue = std::unique_ptr<VehiclePropValue>(
|
||||
new VehiclePropValue(*mSetUserIdentificationAssociationResponseFromCmd));
|
||||
// Must use the same requestId
|
||||
if (value.value.int32Values.size() > 0) {
|
||||
newValue->value.int32Values[0] = value.value.int32Values[0];
|
||||
} else {
|
||||
ALOGE("get(USER_IDENTIFICATION_ASSOCIATION): no requestId on %s",
|
||||
toString(value).c_str());
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
return defaultUserIdentificationAssociation(value);
|
||||
}
|
||||
|
||||
android::base::Result<std::unique_ptr<VehiclePropValue>>
|
||||
EmulatedUserHal::onSetInitialUserInfoResponse(const VehiclePropValue& value) {
|
||||
if (value.value.int32Values.size() == 0) {
|
||||
@@ -147,6 +168,20 @@ android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetS
|
||||
return sendUserHalResponse(std::move(mSwitchUserResponseFromCmd), requestId);
|
||||
}
|
||||
|
||||
if (value.value.int32Values.size() > 1) {
|
||||
auto messageType = static_cast<SwitchUserMessageType>(value.value.int32Values[1]);
|
||||
switch (messageType) {
|
||||
case SwitchUserMessageType::LEGACY_ANDROID_SWITCH:
|
||||
ALOGI("request is LEGACY_ANDROID_SWITCH; ignoring it");
|
||||
return {};
|
||||
case SwitchUserMessageType::ANDROID_POST_SWITCH:
|
||||
ALOGI("request is ANDROID_POST_SWITCH; ignoring it");
|
||||
return {};
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns default response
|
||||
auto updatedValue = std::unique_ptr<VehiclePropValue>(new VehiclePropValue);
|
||||
updatedValue->prop = SWITCH_USER;
|
||||
@@ -162,6 +197,41 @@ android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetS
|
||||
return updatedValue;
|
||||
}
|
||||
|
||||
android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetCreateUserResponse(
|
||||
const VehiclePropValue& value) {
|
||||
if (value.value.int32Values.size() == 0) {
|
||||
ALOGE("set(CREATE_USER): no int32values, ignoring it: %s", toString(value).c_str());
|
||||
return android::base::Error(static_cast<int>(StatusCode::INVALID_ARG))
|
||||
<< "no int32values on " << toString(value);
|
||||
}
|
||||
|
||||
if (value.areaId != 0) {
|
||||
ALOGD("set(CREATE_USER) called from lshal; storing it: %s", toString(value).c_str());
|
||||
mCreateUserResponseFromCmd.reset(new VehiclePropValue(value));
|
||||
return {};
|
||||
}
|
||||
ALOGD("set(CREATE_USER) called from Android: %s", toString(value).c_str());
|
||||
|
||||
int32_t requestId = value.value.int32Values[0];
|
||||
if (mCreateUserResponseFromCmd != nullptr) {
|
||||
ALOGI("replying CREATE_USER with lshal value: %s",
|
||||
toString(*mCreateUserResponseFromCmd).c_str());
|
||||
return sendUserHalResponse(std::move(mCreateUserResponseFromCmd), requestId);
|
||||
}
|
||||
|
||||
// Returns default response
|
||||
auto updatedValue = std::unique_ptr<VehiclePropValue>(new VehiclePropValue);
|
||||
updatedValue->prop = CREATE_USER;
|
||||
updatedValue->timestamp = elapsedRealtimeNano();
|
||||
updatedValue->value.int32Values.resize(2);
|
||||
updatedValue->value.int32Values[0] = requestId;
|
||||
updatedValue->value.int32Values[1] = (int32_t)CreateUserStatus::SUCCESS;
|
||||
|
||||
ALOGI("no lshal response; replying with SUCCESS: %s", toString(*updatedValue).c_str());
|
||||
|
||||
return updatedValue;
|
||||
}
|
||||
|
||||
android::base::Result<std::unique_ptr<VehiclePropValue>>
|
||||
EmulatedUserHal::onSetUserIdentificationAssociation(const VehiclePropValue& value) {
|
||||
if (value.value.int32Values.size() == 0) {
|
||||
@@ -190,16 +260,14 @@ EmulatedUserHal::onSetUserIdentificationAssociation(const VehiclePropValue& valu
|
||||
}
|
||||
|
||||
// Returns default response
|
||||
auto updatedValue = std::unique_ptr<VehiclePropValue>(new VehiclePropValue);
|
||||
updatedValue->prop = USER_IDENTIFICATION_ASSOCIATION;
|
||||
updatedValue->timestamp = elapsedRealtimeNano();
|
||||
updatedValue->value.int32Values.resize(1);
|
||||
updatedValue->value.int32Values[0] = requestId;
|
||||
updatedValue->value.stringValue = "Response not set by LSHAL";
|
||||
return defaultUserIdentificationAssociation(value);
|
||||
}
|
||||
|
||||
ALOGI("no lshal response; replying with an error message: %s", toString(*updatedValue).c_str());
|
||||
|
||||
return updatedValue;
|
||||
android::base::Result<std::unique_ptr<VehiclePropValue>>
|
||||
EmulatedUserHal::defaultUserIdentificationAssociation(const VehiclePropValue& request) {
|
||||
// TODO(b/159498909): return a response with NOT_ASSOCIATED_ANY_USER for all requested types
|
||||
ALOGE("no lshal response for %s; replying with NOT_AVAILABLE", toString(request).c_str());
|
||||
return android::base::Error(static_cast<int>(StatusCode::NOT_AVAILABLE)) << "not set by lshal";
|
||||
}
|
||||
|
||||
android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::sendUserHalResponse(
|
||||
@@ -247,6 +315,12 @@ void EmulatedUserHal::dump(int fd, std::string indent) {
|
||||
} else {
|
||||
dprintf(fd, "%sNo SwitchUser response\n", indent.c_str());
|
||||
}
|
||||
if (mCreateUserResponseFromCmd != nullptr) {
|
||||
dprintf(fd, "%sCreateUser response: %s\n", indent.c_str(),
|
||||
toString(*mCreateUserResponseFromCmd).c_str());
|
||||
} else {
|
||||
dprintf(fd, "%sNo CreateUser response\n", indent.c_str());
|
||||
}
|
||||
if (mSetUserIdentificationAssociationResponseFromCmd != nullptr) {
|
||||
dprintf(fd, "%sSetUserIdentificationAssociation response: %s\n", indent.c_str(),
|
||||
toString(*mSetUserIdentificationAssociationResponseFromCmd).c_str());
|
||||
|
||||
@@ -58,7 +58,8 @@ class EmulatedUserHal {
|
||||
*
|
||||
* @return property value and StatusCode
|
||||
*/
|
||||
android::base::Result<std::unique_ptr<VehiclePropValue>> onGetProperty(int32_t prop);
|
||||
android::base::Result<std::unique_ptr<VehiclePropValue>> onGetProperty(
|
||||
const VehiclePropValue& value);
|
||||
|
||||
/**
|
||||
* Shows the User HAL emulation help.
|
||||
@@ -105,17 +106,37 @@ class EmulatedUserHal {
|
||||
const VehiclePropValue& value);
|
||||
|
||||
/**
|
||||
* Used to emulate USER_IDENTIFICATION_ASSOCIATION - see onSetInitialUserInfoResponse() for
|
||||
* Used to emulate CREATE_USER - see onSetInitialUserInfoResponse() for usage.
|
||||
*/
|
||||
android::base::Result<std::unique_ptr<VehiclePropValue>> onSetCreateUserResponse(
|
||||
const VehiclePropValue& value);
|
||||
|
||||
/**
|
||||
* Used to emulate set USER_IDENTIFICATION_ASSOCIATION - see onSetInitialUserInfoResponse() for
|
||||
* usage.
|
||||
*/
|
||||
android::base::Result<std::unique_ptr<VehiclePropValue>> onSetUserIdentificationAssociation(
|
||||
const VehiclePropValue& value);
|
||||
|
||||
/**
|
||||
* Used to emulate get USER_IDENTIFICATION_ASSOCIATION - see onSetInitialUserInfoResponse() for
|
||||
* usage.
|
||||
*/
|
||||
android::base::Result<std::unique_ptr<VehiclePropValue>> onGetUserIdentificationAssociation(
|
||||
const VehiclePropValue& value);
|
||||
|
||||
/**
|
||||
* Creates a default USER_IDENTIFICATION_ASSOCIATION when it was not set by lshal.
|
||||
*/
|
||||
android::base::Result<std::unique_ptr<VehiclePropValue>> defaultUserIdentificationAssociation(
|
||||
const VehiclePropValue& request);
|
||||
|
||||
android::base::Result<std::unique_ptr<VehiclePropValue>> sendUserHalResponse(
|
||||
std::unique_ptr<VehiclePropValue> response, int32_t requestId);
|
||||
|
||||
std::unique_ptr<VehiclePropValue> mInitialUserResponseFromCmd;
|
||||
std::unique_ptr<VehiclePropValue> mSwitchUserResponseFromCmd;
|
||||
std::unique_ptr<VehiclePropValue> mCreateUserResponseFromCmd;
|
||||
std::unique_ptr<VehiclePropValue> mSetUserIdentificationAssociationResponseFromCmd;
|
||||
};
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::get(
|
||||
default:
|
||||
if (mEmulatedUserHal != nullptr && mEmulatedUserHal->isSupported(propId)) {
|
||||
ALOGI("get(): getting value for prop %d from User HAL", propId);
|
||||
const auto& ret = mEmulatedUserHal->onGetProperty(propId);
|
||||
const auto& ret = mEmulatedUserHal->onGetProperty(requestedPropValue);
|
||||
if (!ret.ok()) {
|
||||
ALOGE("get(): User HAL returned error: %s", ret.error().message().c_str());
|
||||
*outStatus = StatusCode(ret.error().code());
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
cc_library_static {
|
||||
name: "android.hardware.automotive.vehicle@2.0-libproto-native",
|
||||
vendor: true,
|
||||
host_supported: true,
|
||||
proto: {
|
||||
export_proto_headers: true,
|
||||
type: "lite",
|
||||
|
||||
@@ -2532,23 +2532,23 @@ enum VehicleProperty : int32_t {
|
||||
*
|
||||
* int32[0]: 42 // must match the request id from the request
|
||||
* int32[1]: 2 // action = InitialUserInfoResponseAction::CREATE
|
||||
* int32[2]: -1 // userToSwitchOrCreate.userId (not used as user will be created)
|
||||
* int32[2]: -10000 // userToSwitchOrCreate.userId (not used as user will be created)
|
||||
* int32[3]: 8 // userToSwitchOrCreate.flags = ADMIN
|
||||
* string: "||Owner" // userLocales + separator + userNameToCreate
|
||||
* string: "||Owner" // userLocales + separator + userNameToCreate
|
||||
*
|
||||
* Notice the string value represents multiple values, separated by ||. The first value is the
|
||||
* (optional) system locales for the user to be created (in this case, it's empty, meaning it
|
||||
* will use Android's default value), while the second value is the (also optional) name of the
|
||||
* to user to be created (when the type of response is InitialUserInfoResponseAction:CREATE).
|
||||
* For example, to create the same "Owner" user with "en-US" and "pt-BR" locales, the string
|
||||
* value of the response would be "en-US,pt-BR||Owner".
|
||||
* value of the response would be "en-US,pt-BR||Owner". As such, neither the locale nor the
|
||||
* name can have || on it, although a single | is fine.
|
||||
*
|
||||
* NOTE: if the HAL doesn't support user management, then it should not define this property,
|
||||
* 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, CREATE_USER, REMOVE_USER,
|
||||
* and USER_IDENTIFICATION_ASSOCIATION).
|
||||
* by the Android System). But if it supports user management, then it must support all core
|
||||
* user-related properties (INITIAL_USER_INFO, SWITCH_USER, CREATE_USER, and REMOVE_USER).
|
||||
*
|
||||
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
|
||||
* @access VehiclePropertyAccess:READ_WRITE
|
||||
@@ -2627,7 +2627,7 @@ enum VehicleProperty : int32_t {
|
||||
* int32[5]: 0 // current user flags (none)
|
||||
* int32[6]: 3 // number of users
|
||||
* int32[7]: 0 // 1st user (user 0)
|
||||
* int32[8]: 0 // 1st user flags (none)
|
||||
* int32[8]: 1 // 1st user flags (SYSTEM)
|
||||
* int32[9]: 10 // 2nd user (user 10)
|
||||
* int32[10]: 0 // 2nd user flags (none)
|
||||
* int32[11]: 11 // 3rd user (user 11)
|
||||
@@ -2661,7 +2661,7 @@ enum VehicleProperty : int32_t {
|
||||
* identified the user as A.
|
||||
*
|
||||
* The HAL makes this request by a property change event (passing a negative request id), and
|
||||
* the Android system will response by issuye an ANDROID_POST_SWITCH call which the same
|
||||
* the Android system will response by issue an ANDROID_POST_SWITCH call which the same
|
||||
* request id.
|
||||
*
|
||||
* For example, if the current foreground Android user is 10 and the HAL asked it to switch to
|
||||
@@ -2705,7 +2705,7 @@ enum VehicleProperty : int32_t {
|
||||
* in the response are different (as the current user didn't change to the target).
|
||||
* 3. If a new switch request is made before the HAL responded to the previous one or before
|
||||
* the user was unlocked, then the ANDROID_POST_SWITCH request is not made. For example,
|
||||
* the driver could accidentally switch to the wrong user which has lock crentials, then
|
||||
* the driver could accidentally switch to the wrong user which has lock credentials, then
|
||||
* switch to the right one before entering the credentials.
|
||||
*
|
||||
* The HAL can update its internal state once it receives this request, but it doesn't need to
|
||||
@@ -2818,6 +2818,10 @@ enum VehicleProperty : int32_t {
|
||||
* Property used to associate (or query the association) the current user with vehicle-specific
|
||||
* identification mechanisms (such as key FOB).
|
||||
*
|
||||
* This is an optional user management property - the OEM could still support user management
|
||||
* without defining it. In fact, this property could be used without supporting the core
|
||||
* user-related functions described on INITIAL_USER_INFO.
|
||||
*
|
||||
* 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, returning a VehiclePropValue
|
||||
@@ -4277,6 +4281,16 @@ enum UserFlags: int32_t {
|
||||
* Admin users have additional privileges such as permission to create other users.
|
||||
*/
|
||||
ADMIN = 0x08,
|
||||
|
||||
/**
|
||||
* Disabled users are marked for deletion.
|
||||
*/
|
||||
DISABLED = 0x10,
|
||||
|
||||
/**
|
||||
* Profile user is a profile of another user.
|
||||
*/
|
||||
PROFILE = 0x20,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -4291,10 +4305,16 @@ struct UsersInfo {
|
||||
/** The current foreground user. */
|
||||
UserInfo currentUser;
|
||||
|
||||
/** Number of existing users (includes the current user). */
|
||||
/**
|
||||
* Number of existing users; includes the current user, recently removed users (with DISABLED
|
||||
* flag), and profile users (with PROFILE flag).
|
||||
*/
|
||||
int32_t numberUsers;
|
||||
|
||||
/** List of existing users (includes the current user). */
|
||||
/**
|
||||
* List of existing users; includes the current user, recently removed users (with DISABLED
|
||||
* flag), and profile users (with PROFILE flag).
|
||||
*/
|
||||
vec<UserInfo> existingUsers;
|
||||
};
|
||||
|
||||
@@ -4370,16 +4390,16 @@ struct InitialUserInfoResponse {
|
||||
*/
|
||||
UserInfo userToSwitchOrCreate;
|
||||
|
||||
/**
|
||||
* Name of the user that should be created.
|
||||
*/
|
||||
string userNameToCreate;
|
||||
|
||||
/**
|
||||
* System locales of the initial user (value will be passed as-is to
|
||||
* android.provider.Settings.System.SYSTEM_LOCALES)
|
||||
*/
|
||||
string userLocales;
|
||||
|
||||
/**
|
||||
* Name of the user that should be created.
|
||||
*/
|
||||
string userNameToCreate;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <random>
|
||||
#include <thread>
|
||||
|
||||
using android::sp;
|
||||
using android::hardware::hidl_vec;
|
||||
@@ -144,7 +145,10 @@ class FaceHidlTest : public ::testing::TestWithParam<std::string> {
|
||||
ASSERT_EQ(Status::OK, static_cast<Status>(ret2));
|
||||
}
|
||||
|
||||
void TearDown() override {}
|
||||
void TearDown() override {
|
||||
// Hack to allow the asynchronous operations to finish on time.
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
}
|
||||
|
||||
sp<IBiometricsFace> mService;
|
||||
sp<FaceCallback> mCallback;
|
||||
|
||||
@@ -49,7 +49,7 @@ static const uint32_t kTimeout = 3;
|
||||
static const std::chrono::seconds kTimeoutInSeconds = std::chrono::seconds(kTimeout);
|
||||
static const uint32_t kGroupId = 99;
|
||||
static std::string kTmpDir = "";
|
||||
static const uint32_t kIterations = 1000;
|
||||
static const uint32_t kIterations = 10;
|
||||
|
||||
// Wait for a callback to occur (signaled by the given future) up to the
|
||||
// provided timeout. If the future is invalid or the callback does not come
|
||||
|
||||
@@ -26,4 +26,5 @@ cc_test {
|
||||
"general-tests",
|
||||
"vts",
|
||||
],
|
||||
disable_framework: true,
|
||||
}
|
||||
|
||||
@@ -87,15 +87,19 @@ interface ICameraDeviceCallback {
|
||||
* ERROR_RESULT message.
|
||||
*
|
||||
* If an output buffer cannot be filled, its status field must be set to
|
||||
* STATUS_ERROR. In addition, notify() must be called with a ERROR_BUFFER
|
||||
* message.
|
||||
* STATUS_ERROR. In this case, notify() isn't required to be called with
|
||||
* an ERROR_BUFFER message. The framework will simply treat the notify()
|
||||
* call with ERROR_BUFFER as a no-op, and derive whether and when to notify
|
||||
* the application of buffer loss based on the buffer status and whether or not
|
||||
* the entire capture has failed.
|
||||
*
|
||||
* If the entire capture has failed, then this method still needs to be
|
||||
* called to return the output buffers to the framework. All the buffer
|
||||
* statuses must be STATUS_ERROR, and the result metadata must be an
|
||||
* empty buffer. In addition, notify() must be called with a ERROR_REQUEST
|
||||
* message. In this case, individual ERROR_RESULT/ERROR_BUFFER messages
|
||||
* must not be sent.
|
||||
* must not be sent. Note that valid partial results are still allowed
|
||||
* as long as the final result metadata fails to be generated.
|
||||
*
|
||||
* Performance requirements:
|
||||
*
|
||||
|
||||
@@ -38,7 +38,7 @@ bool convertFromHidl(const CameraMetadata &src, const camera_metadata_t** dst) {
|
||||
}
|
||||
|
||||
const uint8_t* data = src.data();
|
||||
// sanity check the size of CameraMetadata match underlying camera_metadata_t
|
||||
// check that the size of CameraMetadata match underlying camera_metadata_t
|
||||
if (get_camera_metadata_size((camera_metadata_t*)data) != src.size()) {
|
||||
ALOGE("%s: input CameraMetadata is corrupt!", __FUNCTION__);
|
||||
return false;
|
||||
|
||||
33
camera/provider/2.4/vts/functional/AndroidTest.xml
Normal file
33
camera/provider/2.4/vts/functional/AndroidTest.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2020 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<configuration description="Runs VtsHalCameraProviderV2_4TargetTest.">
|
||||
<option name="test-suite-tag" value="apct" />
|
||||
<option name="test-suite-tag" value="apct-native" />
|
||||
|
||||
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
|
||||
</target_preparer>
|
||||
|
||||
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
|
||||
<option name="cleanup" value="true" />
|
||||
<option name="push" value="VtsHalCameraProviderV2_4TargetTest->/data/local/tmp/VtsHalCameraProviderV2_4TargetTest" />
|
||||
</target_preparer>
|
||||
|
||||
<test class="com.android.tradefed.testtype.GTest" >
|
||||
<option name="native-test-device-path" value="/data/local/tmp" />
|
||||
<option name="module-name" value="VtsHalCameraProviderV2_4TargetTest" />
|
||||
<option name="native-test-timeout" value="1800000"/> <!-- 30 min -->
|
||||
</test>
|
||||
</configuration>
|
||||
@@ -843,7 +843,7 @@ public:
|
||||
|
||||
void verifyRequestTemplate(const camera_metadata_t* metadata, RequestTemplate requestTemplate);
|
||||
|
||||
bool isDepthOnly(camera_metadata_t* staticMeta);
|
||||
static bool isDepthOnly(const camera_metadata_t* staticMeta);
|
||||
|
||||
static Status getAvailableOutputStreams(const camera_metadata_t *staticMeta,
|
||||
std::vector<AvailableStream> &outputStreams,
|
||||
@@ -1894,7 +1894,7 @@ TEST_P(CameraHidlTest, getCameraDeviceInterface) {
|
||||
}
|
||||
|
||||
// Verify that the device resource cost can be retrieved and the values are
|
||||
// sane.
|
||||
// correct.
|
||||
TEST_P(CameraHidlTest, getResourceCost) {
|
||||
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
|
||||
|
||||
@@ -2544,7 +2544,7 @@ TEST_P(CameraHidlTest, sendCommandSmoothZoom) {
|
||||
}
|
||||
}
|
||||
|
||||
// Basic sanity tests related to camera parameters.
|
||||
// Basic correctness tests related to camera parameters.
|
||||
TEST_P(CameraHidlTest, getSetParameters) {
|
||||
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
|
||||
|
||||
@@ -5537,9 +5537,22 @@ static Size getMinSize(Size a, Size b) {
|
||||
// TODO: Add more combinations
|
||||
Status CameraHidlTest::getMandatoryConcurrentStreams(const camera_metadata_t* staticMeta,
|
||||
std::vector<AvailableStream>* outputStreams) {
|
||||
if (nullptr == staticMeta) {
|
||||
if (nullptr == staticMeta || nullptr == outputStreams) {
|
||||
return Status::ILLEGAL_ARGUMENT;
|
||||
}
|
||||
|
||||
if (isDepthOnly(staticMeta)) {
|
||||
Size y16MaxSize(640, 480);
|
||||
Size maxAvailableY16Size;
|
||||
getMaxOutputSizeForFormat(staticMeta, PixelFormat::Y16, &maxAvailableY16Size);
|
||||
Size y16ChosenSize = getMinSize(y16MaxSize, maxAvailableY16Size);
|
||||
AvailableStream y16Stream = {.width = y16ChosenSize.width,
|
||||
.height = y16ChosenSize.height,
|
||||
.format = static_cast<int32_t>(PixelFormat::Y16)};
|
||||
outputStreams->push_back(y16Stream);
|
||||
return Status::OK;
|
||||
}
|
||||
|
||||
Size yuvMaxSize(1280, 720);
|
||||
Size jpegMaxSize(1920, 1440);
|
||||
Size maxAvailableYuvSize;
|
||||
@@ -6296,7 +6309,7 @@ void CameraHidlTest::configureOfflineStillStream(const std::string &name,
|
||||
ASSERT_TRUE(ret.isOk());
|
||||
}
|
||||
|
||||
bool CameraHidlTest::isDepthOnly(camera_metadata_t* staticMeta) {
|
||||
bool CameraHidlTest::isDepthOnly(const camera_metadata_t* staticMeta) {
|
||||
camera_metadata_ro_entry scalarEntry;
|
||||
camera_metadata_ro_entry depthEntry;
|
||||
|
||||
|
||||
@@ -61,6 +61,12 @@ interface ICameraProvider extends @2.5::ICameraProvider {
|
||||
* outputs, stream combinations mentioned above, where YUV is substituted by
|
||||
* Y8 must be also supported.
|
||||
*
|
||||
* Devices whose capabilities do not include
|
||||
* ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE, must support
|
||||
* at least a single Y16 stream, Dataspace::DEPTH with sVGA resolution,
|
||||
* during concurrent operation.
|
||||
* Where sVGA - min (max output resolution for the given format, 640 X 480)
|
||||
*
|
||||
* The camera framework must call this method whenever it gets a
|
||||
* cameraDeviceStatusChange callback adding a new camera device or removing
|
||||
* a camera device known to it. This is so that the camera framework can get new combinations
|
||||
@@ -76,12 +82,16 @@ interface ICameraProvider extends @2.5::ICameraProvider {
|
||||
* configuration settings exposed through camera metadata), should the sum
|
||||
* of resource costs for the combination be <= 100.
|
||||
*
|
||||
* The lists of camera id combinations returned by this method may contain
|
||||
* hidden physical camera ids. If a combination does contain hidden physical
|
||||
* camera ids, the camera framework must be able to open any logical cameras
|
||||
* that contain these hidden physical camera ids in their
|
||||
* ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS list, in addition to the other
|
||||
* camera ids advertised in the combination, for concurrent operation.
|
||||
* For guaranteed concurrent camera operation, the camera framework must call
|
||||
* ICameraDevice.open() on all devices (intended for concurrent operation), before configuring
|
||||
* any streams on them. This gives the camera HAL process an opportunity to potentially
|
||||
* distribute hardware resources better before stream configuration.
|
||||
*
|
||||
* Due to potential hardware constraints around internal switching of physical camera devices,
|
||||
* a device's complete ZOOM_RATIO_RANGE(if supported), may not apply during concurrent
|
||||
* operation. If ZOOM_RATIO is supported, camera HALs must ensure ZOOM_RATIO_RANGE of
|
||||
* [1.0, ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM] is supported by that device, during
|
||||
* concurrent operation.
|
||||
*
|
||||
* @return status Status code for the operation
|
||||
* @return cameraIds a list of camera id combinations that support
|
||||
|
||||
@@ -588,6 +588,7 @@ c3ec182ce325862b7d79e526f3e170c02cfee1497ed309d7c60d0de4ca636b0b android.hardwar
|
||||
578f640c653726d58f99c84a7e1bb63862e21ef7cbb4f7d95c3cc62de00dca35 android.hardware.automotive.evs@1.0::IEvsDisplay
|
||||
f5bc6aa840db933cb9fd36668b06d3e2021cf5384bb70e459f22e2f2f921fba5 android.hardware.automotive.evs@1.0::IEvsEnumerator
|
||||
d3a344b7bd4c0d2658ae7209f55a979b8f53f361fd00f4fca29d5baa56d11fd2 android.hardware.automotive.evs@1.0::types
|
||||
2924c3e43858190ee3e2da4c2fb93bba8ae065fe314451f035a7ec52cb80c94a android.hardware.camera.device@3.2::ICameraDeviceCallback # b/155353799
|
||||
2410dd02d67786a732d36e80b0f8ccf55086604ef37f9838e2013ff2c571e404 android.hardware.camera.device@3.5::types
|
||||
cd06a7911b9acd4a653bbf7133888878fbcb3f84be177c7a3f1becaae3d8618f android.hardware.camera.metadata@3.2::types
|
||||
5cf81b1001296fbb3c5b3d275a859244f61cec5fa858d7be9cca46c5b7dfa733 android.hardware.camera.metadata@3.2::types # b/150331548
|
||||
@@ -657,7 +658,7 @@ ca515ff4b63c80cf5ad7b3395c997c57d6c56157361f6c367d1c96f23cc4860a android.hardwar
|
||||
87958d728d7c0ee9b9391ab4a072b097914921a7b38f7dc3df427f933a5b528e android.hardware.automotive.evs@1.1::IEvsEnumerator
|
||||
f53b4e8de6209c6d0fa9036005671b34a2f98328b51423d3a5137a43bf42c84d android.hardware.automotive.evs@1.1::IEvsUltrasonicsArray
|
||||
0460bacbde906a846a3d71b2b7b33d6927cac3ff072e523ffac7853577464406 android.hardware.automotive.evs@1.1::IEvsUltrasonicsArrayStream
|
||||
3e374b5c4777f959f62a320abb3b9edca8874e24e383dbb19c66d224f151b363 android.hardware.automotive.evs@1.1::types
|
||||
f27cf8283e7b953d33dd258734749d2fca9cc63502ea41353060ffa78d8ce9f6 android.hardware.automotive.evs@1.1::types
|
||||
4e4904c4067dadae974ddf90351f362331dcd04bba1d890d313cc8ba91f68c15 android.hardware.automotive.sv@1.0::ISurroundView2dSession
|
||||
63336e9d03f545020ff2982ff76d9d8c44fa76ad476293b5ef6732cbbd71e61b android.hardware.automotive.sv@1.0::ISurroundView3dSession
|
||||
b7015428cd52ce8192d13bfcbf2c4455cda3727d57f2aac80d65a1747104f5ac android.hardware.automotive.sv@1.0::ISurroundViewService
|
||||
@@ -676,7 +677,7 @@ eb90c4d366f05a025d1d1a3672f8b4c3e33e420fa387f73f21b264645bfdf845 android.hardwar
|
||||
a718c8a3acaa938de5a57923e8c4625ed7ca051e05a1d930ba6998557d7b57c8 android.hardware.camera.device@3.6::ICameraOfflineSession
|
||||
a35d5151b48505f06a775b38c0e2e265f80a845d92802324c643565807f81c53 android.hardware.camera.device@3.6::types
|
||||
02bdf82dba7dce273a554b4474468a8fb1fb4f61ab65da95eb16e080df63fff6 android.hardware.camera.metadata@3.5::types
|
||||
21086e1c7a2acc0ebe0ff8561b11f3c2009be687a92d79b608a5f00b16c5f598 android.hardware.camera.provider@2.6::ICameraProvider
|
||||
93cd94e47b22007bbf436c2f5c2703bb7b2859d1b714d6ae15520db55667ba6c android.hardware.camera.provider@2.6::ICameraProvider
|
||||
8f8d9463508ff9cae88eb35c429fd0e2dbca0ca8f5de7fdf836cc0c4370becb6 android.hardware.camera.provider@2.6::ICameraProviderCallback
|
||||
1edf7aef68ef3bd577a1175b1462fb82e3e39f01c6915dda61fba121028df283 android.hardware.camera.provider@2.6::types
|
||||
c1aa508d00b66ed5feefea398fd5edf28fa651ac89773adad7dfda4e0a73a952 android.hardware.cas@1.2::ICas
|
||||
@@ -721,6 +722,7 @@ ee9dc34b9925b8367b1111c72bd6d9d375432735e451572ca5a665d8516a7744 android.hardwar
|
||||
eee3430cc86c97c7b407495863d8fb61da6f1a64b7721e77b9b4909b11b174e9 android.hardware.neuralnetworks@1.3::IPreparedModelCallback
|
||||
acf84925f8ee0a651f2ec547ac334034de266479b93af5434f6c1f25e66aba96 android.hardware.neuralnetworks@1.3::types
|
||||
e9080d04218e98512b63aace9ff3da52f0130238391f15cbbf7df396a3ec9072 android.hardware.neuralnetworks@1.3::types # b/155508675, b/155662254, b/155238914, b/155660285
|
||||
583dc88b41e702e940fd954edda1beb8b4151eab55a5c6d7e69e2781bce84b59 android.hardware.neuralnetworks@1.3::types # b/156918813
|
||||
b454df853441c12f6e425e8a60dd29fda20f5e6e39b93d1103e4b37495db38aa android.hardware.radio@1.5::IRadio
|
||||
fcbb0742a88215ee7a6d7ce0825d253eb2b50391fc6c8c48667f9fd7f6d4549e android.hardware.radio@1.5::IRadioIndication
|
||||
b809193970a91ca637a4b0184767315601d32e3ef3d5992ffbc7a8d14a14f015 android.hardware.radio@1.5::IRadioResponse
|
||||
|
||||
@@ -25,6 +25,7 @@ cc_test {
|
||||
static_libs: [
|
||||
"android.hardware.gnss@1.0",
|
||||
"android.hardware.gnss@1.1",
|
||||
"android.hardware.gnss@2.0",
|
||||
"android.hardware.gnss@common-vts-lib",
|
||||
],
|
||||
shared_libs: [
|
||||
|
||||
@@ -247,3 +247,46 @@ Return<void> GnssHalTest::GnssMeasurementCorrectionsCallback::setCapabilitiesCb(
|
||||
capabilities_cbq_.store(capabilities);
|
||||
return Void();
|
||||
}
|
||||
|
||||
GnssConstellationType_1_0 GnssHalTest::startLocationAndGetNonGpsConstellation() {
|
||||
const int kLocationsToAwait = 3;
|
||||
|
||||
gnss_cb_->location_cbq_.reset();
|
||||
StartAndCheckLocations(kLocationsToAwait);
|
||||
const int location_called_count = gnss_cb_->location_cbq_.calledCount();
|
||||
|
||||
// Tolerate 1 less sv status to handle edge cases in reporting.
|
||||
int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
|
||||
EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
|
||||
ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations (%d received)",
|
||||
sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
|
||||
|
||||
// Find first non-GPS constellation to blacklist. Exclude IRNSS in GnssConstellationType_2_0
|
||||
// as blacklisting of this constellation is not supported in gnss@2.0.
|
||||
const int kGnssSvStatusTimeout = 2;
|
||||
GnssConstellationType_1_0 constellation_to_blacklist = GnssConstellationType_1_0::UNKNOWN;
|
||||
for (int i = 0; i < sv_info_list_cbq_size; ++i) {
|
||||
hidl_vec<IGnssCallback_2_0::GnssSvInfo> sv_info_list;
|
||||
gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_list, kGnssSvStatusTimeout);
|
||||
for (IGnssCallback_2_0::GnssSvInfo sv_info : sv_info_list) {
|
||||
if ((sv_info.v1_0.svFlag & IGnssCallback_2_0::GnssSvFlags::USED_IN_FIX) &&
|
||||
(sv_info.constellation != GnssConstellationType_2_0::UNKNOWN) &&
|
||||
(sv_info.constellation != GnssConstellationType_2_0::IRNSS) &&
|
||||
(sv_info.constellation != GnssConstellationType_2_0::GPS)) {
|
||||
// found a non-GPS V1_0 constellation
|
||||
constellation_to_blacklist = Utils::mapConstellationType(sv_info.constellation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (constellation_to_blacklist != GnssConstellationType_1_0::UNKNOWN) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (constellation_to_blacklist == GnssConstellationType_1_0::UNKNOWN) {
|
||||
ALOGI("No non-GPS constellations found, constellation blacklist test less effective.");
|
||||
// Proceed functionally to blacklist something.
|
||||
constellation_to_blacklist = GnssConstellationType_1_0::GLONASS;
|
||||
}
|
||||
return constellation_to_blacklist;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,9 @@ using android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrec
|
||||
using android::hardware::gnss::V1_0::GnssLocationFlags;
|
||||
using android::hardware::gnss::V2_0::IGnss;
|
||||
|
||||
using GnssConstellationType_1_0 = android::hardware::gnss::V1_0::GnssConstellationType;
|
||||
using GnssConstellationType_2_0 = android::hardware::gnss::V2_0::GnssConstellationType;
|
||||
|
||||
using GnssLocation_1_0 = android::hardware::gnss::V1_0::GnssLocation;
|
||||
using GnssLocation_2_0 = android::hardware::gnss::V2_0::GnssLocation;
|
||||
|
||||
@@ -194,6 +197,16 @@ class GnssHalTest : public testing::TestWithParam<std::string> {
|
||||
*/
|
||||
void SetPositionMode(const int min_interval_msec, const bool low_power_mode);
|
||||
|
||||
/*
|
||||
* startLocationAndGetNonGpsConstellation:
|
||||
* 1. Start location
|
||||
* 2. Find and return first non-GPS constellation
|
||||
*
|
||||
* Note that location is not stopped in this method. The client should call
|
||||
* StopAndClearLocations() after the call.
|
||||
*/
|
||||
GnssConstellationType_1_0 startLocationAndGetNonGpsConstellation();
|
||||
|
||||
sp<IGnss> gnss_hal_; // GNSS HAL to call into
|
||||
sp<GnssCallback> gnss_cb_; // Primary callback interface
|
||||
};
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
using android::hardware::hidl_string;
|
||||
using android::hardware::hidl_vec;
|
||||
|
||||
using GnssConstellationType_2_0 = android::hardware::gnss::V2_0::GnssConstellationType;
|
||||
using GnssConstellationType_1_0 = android::hardware::gnss::V1_0::GnssConstellationType;
|
||||
using IGnssConfiguration_2_0 = android::hardware::gnss::V2_0::IGnssConfiguration;
|
||||
using IGnssConfiguration_1_1 = android::hardware::gnss::V1_1::IGnssConfiguration;
|
||||
using IAGnssRil_2_0 = android::hardware::gnss::V2_0::IAGnssRil;
|
||||
@@ -491,31 +489,6 @@ TEST_P(GnssHalTest, GetLocationLowPower) {
|
||||
StopAndClearLocations();
|
||||
}
|
||||
|
||||
/*
|
||||
* MapConstellationType:
|
||||
* Given a GnssConstellationType_2_0 type constellation, maps to its equivalent
|
||||
* GnssConstellationType_1_0 type constellation. For constellations that do not have
|
||||
* an equivalent value, maps to GnssConstellationType_1_0::UNKNOWN
|
||||
*/
|
||||
GnssConstellationType_1_0 MapConstellationType(GnssConstellationType_2_0 constellation) {
|
||||
switch (constellation) {
|
||||
case GnssConstellationType_2_0::GPS:
|
||||
return GnssConstellationType_1_0::GPS;
|
||||
case GnssConstellationType_2_0::SBAS:
|
||||
return GnssConstellationType_1_0::SBAS;
|
||||
case GnssConstellationType_2_0::GLONASS:
|
||||
return GnssConstellationType_1_0::GLONASS;
|
||||
case GnssConstellationType_2_0::QZSS:
|
||||
return GnssConstellationType_1_0::QZSS;
|
||||
case GnssConstellationType_2_0::BEIDOU:
|
||||
return GnssConstellationType_1_0::BEIDOU;
|
||||
case GnssConstellationType_2_0::GALILEO:
|
||||
return GnssConstellationType_1_0::GALILEO;
|
||||
default:
|
||||
return GnssConstellationType_1_0::UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* FindStrongFrequentNonGpsSource:
|
||||
*
|
||||
@@ -555,7 +528,7 @@ IGnssConfiguration_1_1::BlacklistedSource FindStrongFrequentNonGpsSource(
|
||||
(sv_info.constellation != GnssConstellationType_2_0::GPS)) {
|
||||
ComparableBlacklistedSource source;
|
||||
source.id.svid = sv_info.v1_0.svid;
|
||||
source.id.constellation = MapConstellationType(sv_info.constellation);
|
||||
source.id.constellation = Utils::mapConstellationType(sv_info.constellation);
|
||||
|
||||
const auto& itSignal = mapSignals.find(source);
|
||||
if (itSignal == mapSignals.end()) {
|
||||
@@ -694,7 +667,7 @@ TEST_P(GnssHalTest, BlacklistIndividualSatellites) {
|
||||
hidl_vec<IGnssCallback_2_0::GnssSvInfo> sv_info_list;
|
||||
gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_list, kGnssSvStatusTimeout);
|
||||
for (IGnssCallback_2_0::GnssSvInfo sv_info : sv_info_list) {
|
||||
auto constellation = MapConstellationType(sv_info.constellation);
|
||||
auto constellation = Utils::mapConstellationType(sv_info.constellation);
|
||||
EXPECT_FALSE((sv_info.v1_0.svid == source_to_blacklist.svid) &&
|
||||
(constellation == source_to_blacklist.constellation) &&
|
||||
(sv_info.v1_0.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX));
|
||||
@@ -736,7 +709,7 @@ TEST_P(GnssHalTest, BlacklistIndividualSatellites) {
|
||||
hidl_vec<IGnssCallback_2_0::GnssSvInfo> sv_info_list;
|
||||
gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_list, kGnssSvStatusTimeout);
|
||||
for (IGnssCallback_2_0::GnssSvInfo sv_info : sv_info_list) {
|
||||
auto constellation = MapConstellationType(sv_info.constellation);
|
||||
auto constellation = Utils::mapConstellationType(sv_info.constellation);
|
||||
if ((sv_info.v1_0.svid == source_to_blacklist.svid) &&
|
||||
(constellation == source_to_blacklist.constellation) &&
|
||||
(sv_info.v1_0.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX)) {
|
||||
@@ -752,7 +725,7 @@ TEST_P(GnssHalTest, BlacklistIndividualSatellites) {
|
||||
}
|
||||
|
||||
/*
|
||||
* BlacklistConstellation:
|
||||
* BlacklistConstellationWithLocationOff:
|
||||
*
|
||||
* 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
|
||||
* GnssStatus for any non-GPS constellations.
|
||||
@@ -761,12 +734,11 @@ TEST_P(GnssHalTest, BlacklistIndividualSatellites) {
|
||||
* GnssStatus does not use any constellation but GPS.
|
||||
* 4a & b) Clean up by turning off location, and send in empty blacklist.
|
||||
*/
|
||||
TEST_P(GnssHalTest, BlacklistConstellation) {
|
||||
TEST_P(GnssHalTest, BlacklistConstellationWithLocationOff) {
|
||||
if (!IsGnssHalVersion_2_0()) {
|
||||
ALOGI("Test BlacklistConstellation skipped. GNSS HAL version is greater than 2.0.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(gnss_cb_->last_capabilities_ & IGnssCallback::Capabilities::SATELLITE_BLACKLIST)) {
|
||||
ALOGI("Test BlacklistConstellation skipped. SATELLITE_BLACKLIST capability not supported.");
|
||||
return;
|
||||
@@ -774,43 +746,12 @@ TEST_P(GnssHalTest, BlacklistConstellation) {
|
||||
|
||||
const int kLocationsToAwait = 3;
|
||||
|
||||
gnss_cb_->location_cbq_.reset();
|
||||
StartAndCheckLocations(kLocationsToAwait);
|
||||
const int location_called_count = gnss_cb_->location_cbq_.calledCount();
|
||||
// Find first non-GPS constellation to blacklist
|
||||
GnssConstellationType_1_0 constellation_to_blacklist = startLocationAndGetNonGpsConstellation();
|
||||
|
||||
// Tolerate 1 less sv status to handle edge cases in reporting.
|
||||
int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
|
||||
EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
|
||||
ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations (%d received)",
|
||||
sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
|
||||
// Turns off location
|
||||
StopAndClearLocations();
|
||||
|
||||
// Find first non-GPS constellation to blacklist. Exclude IRNSS in GnssConstellationType_2_0
|
||||
// as blacklisting of this constellation is not supported in gnss@2.0.
|
||||
const int kGnssSvStatusTimeout = 2;
|
||||
GnssConstellationType_1_0 constellation_to_blacklist = GnssConstellationType_1_0::UNKNOWN;
|
||||
for (int i = 0; i < sv_info_list_cbq_size; ++i) {
|
||||
hidl_vec<IGnssCallback_2_0::GnssSvInfo> sv_info_list;
|
||||
gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_list, kGnssSvStatusTimeout);
|
||||
for (IGnssCallback_2_0::GnssSvInfo sv_info : sv_info_list) {
|
||||
if ((sv_info.v1_0.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX) &&
|
||||
(sv_info.constellation != GnssConstellationType_2_0::UNKNOWN) &&
|
||||
(sv_info.constellation != GnssConstellationType_2_0::IRNSS) &&
|
||||
(sv_info.constellation != GnssConstellationType_2_0::GPS)) {
|
||||
// found a non-GPS V1_0 constellation
|
||||
constellation_to_blacklist = MapConstellationType(sv_info.constellation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (constellation_to_blacklist != GnssConstellationType_1_0::UNKNOWN) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (constellation_to_blacklist == GnssConstellationType_1_0::UNKNOWN) {
|
||||
ALOGI("No non-GPS constellations found, constellation blacklist test less effective.");
|
||||
// Proceed functionally to blacklist something.
|
||||
constellation_to_blacklist = GnssConstellationType_1_0::GLONASS;
|
||||
}
|
||||
IGnssConfiguration_1_1::BlacklistedSource source_to_blacklist;
|
||||
source_to_blacklist.constellation = constellation_to_blacklist;
|
||||
source_to_blacklist.svid = 0; // documented wildcard for all satellites in this constellation
|
||||
@@ -824,6 +765,7 @@ TEST_P(GnssHalTest, BlacklistConstellation) {
|
||||
sources.resize(1);
|
||||
sources[0] = source_to_blacklist;
|
||||
|
||||
// setBlacklist when location is off.
|
||||
auto result = gnss_configuration_hal->setBlacklist(sources);
|
||||
ASSERT_TRUE(result.isOk());
|
||||
EXPECT_TRUE(result);
|
||||
@@ -835,15 +777,93 @@ TEST_P(GnssHalTest, BlacklistConstellation) {
|
||||
StartAndCheckLocations(kLocationsToAwait);
|
||||
|
||||
// Tolerate 1 less sv status to handle edge cases in reporting.
|
||||
sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
|
||||
int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
|
||||
EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
|
||||
ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations", sv_info_list_cbq_size,
|
||||
kLocationsToAwait);
|
||||
const int kGnssSvStatusTimeout = 2;
|
||||
for (int i = 0; i < sv_info_list_cbq_size; ++i) {
|
||||
hidl_vec<IGnssCallback_2_0::GnssSvInfo> sv_info_list;
|
||||
gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_list, kGnssSvStatusTimeout);
|
||||
for (IGnssCallback_2_0::GnssSvInfo sv_info : sv_info_list) {
|
||||
auto constellation = MapConstellationType(sv_info.constellation);
|
||||
auto constellation = Utils::mapConstellationType(sv_info.constellation);
|
||||
EXPECT_FALSE((constellation == source_to_blacklist.constellation) &&
|
||||
(sv_info.v1_0.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX));
|
||||
}
|
||||
}
|
||||
|
||||
// clean up
|
||||
StopAndClearLocations();
|
||||
sources.resize(0);
|
||||
result = gnss_configuration_hal->setBlacklist(sources);
|
||||
ASSERT_TRUE(result.isOk());
|
||||
EXPECT_TRUE(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* BlacklistConstellationWithLocationOn:
|
||||
*
|
||||
* 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
|
||||
* GnssStatus for any non-GPS constellations.
|
||||
* 2a & b) Blacklist first non-GPS constellations, and turns off location.
|
||||
* 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
|
||||
* GnssStatus does not use any constellation but GPS.
|
||||
* 4a & b) Clean up by turning off location, and send in empty blacklist.
|
||||
*/
|
||||
TEST_P(GnssHalTest, BlacklistConstellationWithLocationOn) {
|
||||
if (!IsGnssHalVersion_2_0()) {
|
||||
ALOGI("Test BlacklistConstellation skipped. GNSS HAL version is greater than 2.0.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(gnss_cb_->last_capabilities_ & IGnssCallback::Capabilities::SATELLITE_BLACKLIST)) {
|
||||
ALOGI("Test BlacklistConstellation skipped. SATELLITE_BLACKLIST capability not supported.");
|
||||
return;
|
||||
}
|
||||
|
||||
const int kLocationsToAwait = 3;
|
||||
|
||||
// Find first non-GPS constellation to blacklist
|
||||
GnssConstellationType_1_0 constellation_to_blacklist = startLocationAndGetNonGpsConstellation();
|
||||
|
||||
IGnssConfiguration_1_1::BlacklistedSource source_to_blacklist;
|
||||
source_to_blacklist.constellation = constellation_to_blacklist;
|
||||
source_to_blacklist.svid = 0; // documented wildcard for all satellites in this constellation
|
||||
|
||||
auto gnss_configuration_hal_return = gnss_hal_->getExtensionGnssConfiguration_1_1();
|
||||
ASSERT_TRUE(gnss_configuration_hal_return.isOk());
|
||||
sp<IGnssConfiguration_1_1> gnss_configuration_hal = gnss_configuration_hal_return;
|
||||
ASSERT_NE(gnss_configuration_hal, nullptr);
|
||||
|
||||
hidl_vec<IGnssConfiguration_1_1::BlacklistedSource> sources;
|
||||
sources.resize(1);
|
||||
sources[0] = source_to_blacklist;
|
||||
|
||||
// setBlacklist when location is on.
|
||||
auto result = gnss_configuration_hal->setBlacklist(sources);
|
||||
ASSERT_TRUE(result.isOk());
|
||||
EXPECT_TRUE(result);
|
||||
|
||||
// Turns off location
|
||||
StopAndClearLocations();
|
||||
|
||||
// retry and ensure constellation not used
|
||||
gnss_cb_->sv_info_list_cbq_.reset();
|
||||
|
||||
gnss_cb_->location_cbq_.reset();
|
||||
StartAndCheckLocations(kLocationsToAwait);
|
||||
|
||||
// Tolerate 1 less sv status to handle edge cases in reporting.
|
||||
int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
|
||||
EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
|
||||
ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations", sv_info_list_cbq_size,
|
||||
kLocationsToAwait);
|
||||
const int kGnssSvStatusTimeout = 2;
|
||||
for (int i = 0; i < sv_info_list_cbq_size; ++i) {
|
||||
hidl_vec<IGnssCallback_2_0::GnssSvInfo> sv_info_list;
|
||||
gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_list, kGnssSvStatusTimeout);
|
||||
for (IGnssCallback_2_0::GnssSvInfo sv_info : sv_info_list) {
|
||||
auto constellation = Utils::mapConstellationType(sv_info.constellation);
|
||||
EXPECT_FALSE((constellation == source_to_blacklist.constellation) &&
|
||||
(sv_info.v1_0.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX));
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ cc_library_static {
|
||||
export_include_dirs: ["include"],
|
||||
shared_libs: [
|
||||
"android.hardware.gnss@1.0",
|
||||
"android.hardware.gnss@2.0",
|
||||
"android.hardware.gnss.measurement_corrections@1.0",
|
||||
"android.hardware.gnss.measurement_corrections@1.1",
|
||||
],
|
||||
|
||||
@@ -169,6 +169,31 @@ const MeasurementCorrections_1_1 Utils::getMockMeasurementCorrections_1_1() {
|
||||
return mockCorrections_1_1;
|
||||
}
|
||||
|
||||
/*
|
||||
* MapConstellationType:
|
||||
* Given a GnssConstellationType_2_0 type constellation, maps to its equivalent
|
||||
* GnssConstellationType_1_0 type constellation. For constellations that do not have
|
||||
* an equivalent value, maps to GnssConstellationType_1_0::UNKNOWN
|
||||
*/
|
||||
GnssConstellationType_1_0 Utils::mapConstellationType(GnssConstellationType_2_0 constellation) {
|
||||
switch (constellation) {
|
||||
case GnssConstellationType_2_0::GPS:
|
||||
return GnssConstellationType_1_0::GPS;
|
||||
case GnssConstellationType_2_0::SBAS:
|
||||
return GnssConstellationType_1_0::SBAS;
|
||||
case GnssConstellationType_2_0::GLONASS:
|
||||
return GnssConstellationType_1_0::GLONASS;
|
||||
case GnssConstellationType_2_0::QZSS:
|
||||
return GnssConstellationType_1_0::QZSS;
|
||||
case GnssConstellationType_2_0::BEIDOU:
|
||||
return GnssConstellationType_1_0::BEIDOU;
|
||||
case GnssConstellationType_2_0::GALILEO:
|
||||
return GnssConstellationType_1_0::GALILEO;
|
||||
default:
|
||||
return GnssConstellationType_1_0::UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace common
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
|
||||
@@ -18,9 +18,12 @@
|
||||
#define android_hardware_gnss_common_vts_Utils_H_
|
||||
|
||||
#include <android/hardware/gnss/1.0/IGnss.h>
|
||||
#include <android/hardware/gnss/2.0/IGnss.h>
|
||||
#include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
|
||||
#include <android/hardware/gnss/measurement_corrections/1.1/IMeasurementCorrections.h>
|
||||
|
||||
using GnssConstellationType_1_0 = android::hardware::gnss::V1_0::GnssConstellationType;
|
||||
using GnssConstellationType_2_0 = android::hardware::gnss::V2_0::GnssConstellationType;
|
||||
using GnssLocation = ::android::hardware::gnss::V1_0::GnssLocation;
|
||||
using namespace android::hardware::gnss::measurement_corrections::V1_0;
|
||||
|
||||
@@ -44,6 +47,8 @@ struct Utils {
|
||||
bool check_more_accuracies);
|
||||
static const MeasurementCorrections_1_0 getMockMeasurementCorrections();
|
||||
static const MeasurementCorrections_1_1 getMockMeasurementCorrections_1_1();
|
||||
|
||||
static GnssConstellationType_1_0 mapConstellationType(GnssConstellationType_2_0 constellation);
|
||||
};
|
||||
|
||||
} // namespace common
|
||||
|
||||
@@ -100,10 +100,11 @@ parcelable PlaneLayout {
|
||||
long totalSizeInBytes;
|
||||
|
||||
/**
|
||||
* Horizontal and vertical subsampling. Must be a positive power of 2.
|
||||
* Horizontal and vertical subsampling. Must be a positive power of 2. A value of 1
|
||||
* indicates no subsampling.
|
||||
*
|
||||
* These fields indicate the number of horizontally or vertically adjacent pixels that use
|
||||
* the same pixel data. A value of 1 indicates no subsampling.
|
||||
* the same pixel data.
|
||||
*/
|
||||
long horizontalSubsampling;
|
||||
long verticalSubsampling;
|
||||
|
||||
@@ -23,6 +23,10 @@ cc_test {
|
||||
shared_libs: [
|
||||
"libfmq",
|
||||
"libsync",
|
||||
"android.hardware.graphics.mapper@2.0",
|
||||
"android.hardware.graphics.mapper@2.1",
|
||||
"android.hardware.graphics.mapper@3.0",
|
||||
"android.hardware.graphics.mapper@4.0",
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.graphics.allocator@2.0",
|
||||
@@ -30,13 +34,9 @@ cc_test {
|
||||
"android.hardware.graphics.allocator@4.0",
|
||||
"android.hardware.graphics.composer@2.1",
|
||||
"android.hardware.graphics.composer@2.1-vts",
|
||||
"android.hardware.graphics.mapper@2.0",
|
||||
"android.hardware.graphics.mapper@2.0-vts",
|
||||
"android.hardware.graphics.mapper@2.1",
|
||||
"android.hardware.graphics.mapper@2.1-vts",
|
||||
"android.hardware.graphics.mapper@3.0",
|
||||
"android.hardware.graphics.mapper@3.0-vts",
|
||||
"android.hardware.graphics.mapper@4.0",
|
||||
"android.hardware.graphics.mapper@4.0-vts",
|
||||
],
|
||||
header_libs: [
|
||||
|
||||
@@ -33,6 +33,10 @@ cc_test {
|
||||
"libprocessgroup",
|
||||
"libsync",
|
||||
"libui",
|
||||
"android.hardware.graphics.mapper@2.0",
|
||||
"android.hardware.graphics.mapper@2.1",
|
||||
"android.hardware.graphics.mapper@3.0",
|
||||
"android.hardware.graphics.mapper@4.0",
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.graphics.allocator@2.0",
|
||||
@@ -43,13 +47,9 @@ cc_test {
|
||||
"android.hardware.graphics.composer@2.1-vts",
|
||||
"android.hardware.graphics.composer@2.2",
|
||||
"android.hardware.graphics.composer@2.2-vts",
|
||||
"android.hardware.graphics.mapper@2.0",
|
||||
"android.hardware.graphics.mapper@2.0-vts",
|
||||
"android.hardware.graphics.mapper@2.1",
|
||||
"android.hardware.graphics.mapper@2.1-vts",
|
||||
"android.hardware.graphics.mapper@3.0",
|
||||
"android.hardware.graphics.mapper@3.0-vts",
|
||||
"android.hardware.graphics.mapper@4.0",
|
||||
"android.hardware.graphics.mapper@4.0-vts",
|
||||
"libgtest",
|
||||
"librenderengine",
|
||||
|
||||
@@ -24,6 +24,10 @@ cc_test {
|
||||
"libfmq",
|
||||
"libhidlbase",
|
||||
"libsync",
|
||||
"android.hardware.graphics.mapper@2.0",
|
||||
"android.hardware.graphics.mapper@2.1",
|
||||
"android.hardware.graphics.mapper@3.0",
|
||||
"android.hardware.graphics.mapper@4.0",
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.graphics.allocator@2.0",
|
||||
@@ -35,13 +39,9 @@ cc_test {
|
||||
"android.hardware.graphics.composer@2.2-vts",
|
||||
"android.hardware.graphics.composer@2.3",
|
||||
"android.hardware.graphics.composer@2.3-vts",
|
||||
"android.hardware.graphics.mapper@2.0",
|
||||
"android.hardware.graphics.mapper@2.0-vts",
|
||||
"android.hardware.graphics.mapper@2.1",
|
||||
"android.hardware.graphics.mapper@2.1-vts",
|
||||
"android.hardware.graphics.mapper@3.0",
|
||||
"android.hardware.graphics.mapper@3.0-vts",
|
||||
"android.hardware.graphics.mapper@4.0",
|
||||
"android.hardware.graphics.mapper@4.0-vts",
|
||||
],
|
||||
header_libs: [
|
||||
|
||||
@@ -23,6 +23,10 @@ cc_test {
|
||||
shared_libs: [
|
||||
"libfmq",
|
||||
"libsync",
|
||||
"android.hardware.graphics.mapper@2.0",
|
||||
"android.hardware.graphics.mapper@2.1",
|
||||
"android.hardware.graphics.mapper@3.0",
|
||||
"android.hardware.graphics.mapper@4.0",
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.graphics.allocator@2.0",
|
||||
@@ -36,13 +40,9 @@ cc_test {
|
||||
"android.hardware.graphics.composer@2.3-vts",
|
||||
"android.hardware.graphics.composer@2.4",
|
||||
"android.hardware.graphics.composer@2.4-vts",
|
||||
"android.hardware.graphics.mapper@2.0",
|
||||
"android.hardware.graphics.mapper@2.0-vts",
|
||||
"android.hardware.graphics.mapper@2.1",
|
||||
"android.hardware.graphics.mapper@2.1-vts",
|
||||
"android.hardware.graphics.mapper@3.0",
|
||||
"android.hardware.graphics.mapper@3.0-vts",
|
||||
"android.hardware.graphics.mapper@4.0",
|
||||
"android.hardware.graphics.mapper@4.0-vts",
|
||||
],
|
||||
header_libs: [
|
||||
|
||||
@@ -414,12 +414,9 @@ void GraphicsComposerHidlCommandTest::sendRefreshFrame(const VsyncPeriodChangeTi
|
||||
|
||||
mWriter->validateDisplay();
|
||||
execute();
|
||||
if (mReader->mCompositionChanges.size() != 0) {
|
||||
GTEST_SUCCEED() << "Composition change requested, skipping test";
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT_EQ(0, mReader->mErrors.size());
|
||||
mReader->mCompositionChanges.clear();
|
||||
|
||||
mWriter->presentDisplay();
|
||||
execute();
|
||||
ASSERT_EQ(0, mReader->mErrors.size());
|
||||
@@ -427,8 +424,14 @@ void GraphicsComposerHidlCommandTest::sendRefreshFrame(const VsyncPeriodChangeTi
|
||||
mWriter->selectLayer(layer);
|
||||
auto handle2 = allocate();
|
||||
ASSERT_NE(nullptr, handle2);
|
||||
|
||||
mWriter->setLayerBuffer(0, handle2, -1);
|
||||
mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>(1, {0, 0, 10, 10}));
|
||||
mWriter->validateDisplay();
|
||||
execute();
|
||||
ASSERT_EQ(0, mReader->mErrors.size());
|
||||
mReader->mCompositionChanges.clear();
|
||||
|
||||
mWriter->presentDisplay();
|
||||
execute();
|
||||
}
|
||||
@@ -490,16 +493,16 @@ void GraphicsComposerHidlCommandTest::Test_setActiveConfigWithConstraints(
|
||||
// At this point the refresh rate should have changed already, however in rare
|
||||
// cases the implementation might have missed the deadline. In this case a new
|
||||
// timeline should have been provided.
|
||||
auto newTimelime = mComposerCallback->takeLastVsyncPeriodChangeTimeline();
|
||||
auto newTimeline = mComposerCallback->takeLastVsyncPeriodChangeTimeline();
|
||||
if (timeline.refreshRequired && refreshMiss) {
|
||||
EXPECT_TRUE(newTimelime.has_value());
|
||||
EXPECT_TRUE(newTimeline.has_value());
|
||||
}
|
||||
|
||||
if (newTimelime.has_value()) {
|
||||
if (timeline.refreshRequired) {
|
||||
sendRefreshFrame(&newTimelime.value());
|
||||
if (newTimeline.has_value()) {
|
||||
if (newTimeline->refreshRequired) {
|
||||
sendRefreshFrame(&newTimeline.value());
|
||||
}
|
||||
waitForVsyncPeriodChange(display, newTimelime.value(), constraints.desiredTimeNanos,
|
||||
waitForVsyncPeriodChange(display, newTimeline.value(), constraints.desiredTimeNanos,
|
||||
vsyncPeriod1, vsyncPeriod2);
|
||||
}
|
||||
|
||||
|
||||
@@ -587,8 +587,8 @@ TEST_P(GraphicsMapperHidlTest, LockUnlockBasic) {
|
||||
static_cast<int32_t>(info.height)};
|
||||
unique_fd fence;
|
||||
uint8_t* data;
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
|
||||
mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage,
|
||||
region, fence.release())));
|
||||
|
||||
// RGBA_8888
|
||||
fillRGBA8888(data, info.height, stride * 4, info.width * 4);
|
||||
@@ -596,8 +596,8 @@ TEST_P(GraphicsMapperHidlTest, LockUnlockBasic) {
|
||||
ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
|
||||
|
||||
// lock again for reading
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
|
||||
mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage,
|
||||
region, fence.release())));
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
verifyRGBA8888(bufferHandle, data, info.height, stride * 4, info.width * 4));
|
||||
@@ -605,6 +605,9 @@ TEST_P(GraphicsMapperHidlTest, LockUnlockBasic) {
|
||||
ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test multiple operations associated with different color formats
|
||||
*/
|
||||
TEST_P(GraphicsMapperHidlTest, Lock_YCRCB_420_SP) {
|
||||
auto info = mDummyDescriptorInfo;
|
||||
info.format = PixelFormat::YCRCB_420_SP;
|
||||
@@ -624,8 +627,8 @@ TEST_P(GraphicsMapperHidlTest, Lock_YCRCB_420_SP) {
|
||||
unique_fd fence;
|
||||
uint8_t* data;
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
|
||||
mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage,
|
||||
region, fence.release())));
|
||||
|
||||
android_ycbcr yCbCr;
|
||||
int64_t hSubsampling = 0;
|
||||
@@ -647,8 +650,8 @@ TEST_P(GraphicsMapperHidlTest, Lock_YCRCB_420_SP) {
|
||||
ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
|
||||
|
||||
// lock again for reading
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
|
||||
mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage,
|
||||
region, fence.release())));
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
getAndroidYCbCr(bufferHandle, data, &yCbCr, &hSubsampling, &vSubsampling));
|
||||
@@ -658,6 +661,56 @@ TEST_P(GraphicsMapperHidlTest, Lock_YCRCB_420_SP) {
|
||||
ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
|
||||
}
|
||||
|
||||
TEST_P(GraphicsMapperHidlTest, YV12SubsampleMetadata) {
|
||||
auto info = mDummyDescriptorInfo;
|
||||
info.format = PixelFormat::YV12;
|
||||
|
||||
const native_handle_t* bufferHandle;
|
||||
uint32_t stride;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
bufferHandle = mGralloc->allocate(info, true, Tolerance::kToleranceStrict, &stride));
|
||||
|
||||
const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
|
||||
static_cast<int32_t>(info.height)};
|
||||
unique_fd fence;
|
||||
ASSERT_NO_FATAL_FAILURE(mGralloc->lock(bufferHandle, info.usage, region, fence.release()));
|
||||
|
||||
hidl_vec<uint8_t> vec;
|
||||
ASSERT_EQ(Error::NONE, mGralloc->get(bufferHandle, gralloc4::MetadataType_PlaneLayouts, &vec));
|
||||
std::vector<PlaneLayout> planeLayouts;
|
||||
ASSERT_EQ(NO_ERROR, gralloc4::decodePlaneLayouts(vec, &planeLayouts));
|
||||
|
||||
ASSERT_EQ(3, planeLayouts.size());
|
||||
|
||||
auto yPlane = planeLayouts[0];
|
||||
auto crPlane = planeLayouts[1];
|
||||
auto cbPlane = planeLayouts[2];
|
||||
|
||||
constexpr uint32_t kCbCrSubSampleFactor = 2;
|
||||
EXPECT_EQ(kCbCrSubSampleFactor, crPlane.horizontalSubsampling);
|
||||
EXPECT_EQ(kCbCrSubSampleFactor, crPlane.verticalSubsampling);
|
||||
|
||||
EXPECT_EQ(kCbCrSubSampleFactor, cbPlane.horizontalSubsampling);
|
||||
EXPECT_EQ(kCbCrSubSampleFactor, cbPlane.verticalSubsampling);
|
||||
|
||||
const long chromaSampleWidth = info.width / kCbCrSubSampleFactor;
|
||||
const long chromaSampleHeight = info.height / kCbCrSubSampleFactor;
|
||||
|
||||
EXPECT_EQ(info.width, yPlane.widthInSamples);
|
||||
EXPECT_EQ(info.height, yPlane.heightInSamples);
|
||||
|
||||
EXPECT_EQ(chromaSampleWidth, crPlane.widthInSamples);
|
||||
EXPECT_EQ(chromaSampleHeight, crPlane.heightInSamples);
|
||||
|
||||
EXPECT_EQ(chromaSampleWidth, cbPlane.widthInSamples);
|
||||
EXPECT_EQ(chromaSampleHeight, cbPlane.heightInSamples);
|
||||
|
||||
EXPECT_LE(crPlane.widthInSamples, crPlane.strideInBytes);
|
||||
EXPECT_LE(cbPlane.widthInSamples, cbPlane.strideInBytes);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
|
||||
}
|
||||
|
||||
TEST_P(GraphicsMapperHidlTest, Lock_YV12) {
|
||||
auto info = mDummyDescriptorInfo;
|
||||
info.format = PixelFormat::YV12;
|
||||
@@ -673,8 +726,8 @@ TEST_P(GraphicsMapperHidlTest, Lock_YV12) {
|
||||
unique_fd fence;
|
||||
uint8_t* data;
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
|
||||
mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage,
|
||||
region, fence.release())));
|
||||
|
||||
android_ycbcr yCbCr;
|
||||
int64_t hSubsampling = 0;
|
||||
@@ -696,8 +749,8 @@ TEST_P(GraphicsMapperHidlTest, Lock_YV12) {
|
||||
ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
|
||||
|
||||
// lock again for reading
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
|
||||
mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage,
|
||||
region, fence.release())));
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
getAndroidYCbCr(bufferHandle, data, &yCbCr, &hSubsampling, &vSubsampling));
|
||||
@@ -722,8 +775,8 @@ TEST_P(GraphicsMapperHidlTest, Lock_YCBCR_420_888) {
|
||||
unique_fd fence;
|
||||
uint8_t* data;
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
|
||||
mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage,
|
||||
region, fence.release())));
|
||||
|
||||
android_ycbcr yCbCr;
|
||||
int64_t hSubsampling = 0;
|
||||
@@ -740,8 +793,8 @@ TEST_P(GraphicsMapperHidlTest, Lock_YCBCR_420_888) {
|
||||
ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
|
||||
|
||||
// lock again for reading
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
|
||||
mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage,
|
||||
region, fence.release())));
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
getAndroidYCbCr(bufferHandle, data, &yCbCr, &hSubsampling, &vSubsampling));
|
||||
@@ -751,6 +804,90 @@ TEST_P(GraphicsMapperHidlTest, Lock_YCBCR_420_888) {
|
||||
ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
|
||||
}
|
||||
|
||||
TEST_P(GraphicsMapperHidlTest, Lock_RAW10) {
|
||||
auto info = mDummyDescriptorInfo;
|
||||
info.format = PixelFormat::RAW10;
|
||||
|
||||
const native_handle_t* bufferHandle;
|
||||
uint32_t stride;
|
||||
ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(
|
||||
info, true, Tolerance::kToleranceUnSupported, &stride));
|
||||
if (bufferHandle == nullptr) {
|
||||
GTEST_SUCCEED() << "RAW10 format is unsupported";
|
||||
return;
|
||||
}
|
||||
|
||||
const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
|
||||
static_cast<int32_t>(info.height)};
|
||||
unique_fd fence;
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(mGralloc->lock(bufferHandle, info.usage, region, fence.release()));
|
||||
|
||||
hidl_vec<uint8_t> vec;
|
||||
ASSERT_EQ(Error::NONE, mGralloc->get(bufferHandle, gralloc4::MetadataType_PlaneLayouts, &vec));
|
||||
std::vector<PlaneLayout> planeLayouts;
|
||||
ASSERT_EQ(NO_ERROR, gralloc4::decodePlaneLayouts(vec, &planeLayouts));
|
||||
|
||||
ASSERT_EQ(1, planeLayouts.size());
|
||||
auto planeLayout = planeLayouts[0];
|
||||
|
||||
EXPECT_EQ(0, planeLayout.sampleIncrementInBits);
|
||||
EXPECT_EQ(1, planeLayout.horizontalSubsampling);
|
||||
EXPECT_EQ(1, planeLayout.verticalSubsampling);
|
||||
|
||||
ASSERT_EQ(1, planeLayout.components.size());
|
||||
auto planeLayoutComponent = planeLayout.components[0];
|
||||
|
||||
EXPECT_EQ(PlaneLayoutComponentType::RAW,
|
||||
static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value));
|
||||
EXPECT_EQ(0, planeLayoutComponent.offsetInBits % 8);
|
||||
EXPECT_EQ(-1, planeLayoutComponent.sizeInBits);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
|
||||
}
|
||||
|
||||
TEST_P(GraphicsMapperHidlTest, Lock_RAW12) {
|
||||
auto info = mDummyDescriptorInfo;
|
||||
info.format = PixelFormat::RAW12;
|
||||
|
||||
const native_handle_t* bufferHandle;
|
||||
uint32_t stride;
|
||||
ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(
|
||||
info, true, Tolerance::kToleranceUnSupported, &stride));
|
||||
if (bufferHandle == nullptr) {
|
||||
GTEST_SUCCEED() << "RAW12 format is unsupported";
|
||||
return;
|
||||
}
|
||||
|
||||
const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
|
||||
static_cast<int32_t>(info.height)};
|
||||
unique_fd fence;
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(mGralloc->lock(bufferHandle, info.usage, region, fence.release()));
|
||||
|
||||
hidl_vec<uint8_t> vec;
|
||||
ASSERT_EQ(Error::NONE, mGralloc->get(bufferHandle, gralloc4::MetadataType_PlaneLayouts, &vec));
|
||||
std::vector<PlaneLayout> planeLayouts;
|
||||
ASSERT_EQ(NO_ERROR, gralloc4::decodePlaneLayouts(vec, &planeLayouts));
|
||||
|
||||
ASSERT_EQ(1, planeLayouts.size());
|
||||
auto planeLayout = planeLayouts[0];
|
||||
|
||||
EXPECT_EQ(0, planeLayout.sampleIncrementInBits);
|
||||
EXPECT_EQ(1, planeLayout.horizontalSubsampling);
|
||||
EXPECT_EQ(1, planeLayout.verticalSubsampling);
|
||||
|
||||
ASSERT_EQ(1, planeLayout.components.size());
|
||||
auto planeLayoutComponent = planeLayout.components[0];
|
||||
|
||||
EXPECT_EQ(PlaneLayoutComponentType::RAW,
|
||||
static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value));
|
||||
EXPECT_EQ(0, planeLayoutComponent.offsetInBits % 8);
|
||||
EXPECT_EQ(-1, planeLayoutComponent.sizeInBits);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test IMapper::unlock with bad access region
|
||||
*/
|
||||
@@ -1706,6 +1843,84 @@ TEST_P(GraphicsMapperHidlTest, SetMetadataNullBuffer) {
|
||||
mGralloc->set(bufferHandle, gralloc4::MetadataType_Smpte2094_40, vec));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get::metadata with cloned native_handle
|
||||
*/
|
||||
TEST_P(GraphicsMapperHidlTest, GetMetadataClonedHandle) {
|
||||
const native_handle_t* bufferHandle = nullptr;
|
||||
ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
|
||||
|
||||
const auto dataspace = Dataspace::SRGB_LINEAR;
|
||||
{
|
||||
hidl_vec<uint8_t> metadata;
|
||||
ASSERT_EQ(NO_ERROR, gralloc4::encodeDataspace(dataspace, &metadata));
|
||||
|
||||
Error err = mGralloc->set(bufferHandle, gralloc4::MetadataType_Dataspace, metadata);
|
||||
if (err == Error::UNSUPPORTED) {
|
||||
GTEST_SUCCEED() << "setting this metadata is unsupported";
|
||||
return;
|
||||
}
|
||||
ASSERT_EQ(Error::NONE, err);
|
||||
}
|
||||
|
||||
const native_handle_t* importedHandle;
|
||||
{
|
||||
auto clonedHandle = native_handle_clone(bufferHandle);
|
||||
ASSERT_NO_FATAL_FAILURE(importedHandle = mGralloc->importBuffer(clonedHandle));
|
||||
native_handle_close(clonedHandle);
|
||||
native_handle_delete(clonedHandle);
|
||||
}
|
||||
|
||||
Dataspace realSpace = Dataspace::UNKNOWN;
|
||||
{
|
||||
hidl_vec<uint8_t> metadata;
|
||||
ASSERT_EQ(Error::NONE,
|
||||
mGralloc->get(importedHandle, gralloc4::MetadataType_Dataspace, &metadata));
|
||||
ASSERT_NO_FATAL_FAILURE(gralloc4::decodeDataspace(metadata, &realSpace));
|
||||
}
|
||||
|
||||
EXPECT_EQ(dataspace, realSpace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set::metadata with cloned native_handle
|
||||
*/
|
||||
TEST_P(GraphicsMapperHidlTest, SetMetadataClonedHandle) {
|
||||
const native_handle_t* bufferHandle = nullptr;
|
||||
ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
|
||||
|
||||
const native_handle_t* importedHandle;
|
||||
{
|
||||
auto clonedHandle = native_handle_clone(bufferHandle);
|
||||
ASSERT_NO_FATAL_FAILURE(importedHandle = mGralloc->importBuffer(clonedHandle));
|
||||
native_handle_close(clonedHandle);
|
||||
native_handle_delete(clonedHandle);
|
||||
}
|
||||
|
||||
const auto dataspace = Dataspace::SRGB_LINEAR;
|
||||
{
|
||||
hidl_vec<uint8_t> metadata;
|
||||
ASSERT_EQ(NO_ERROR, gralloc4::encodeDataspace(dataspace, &metadata));
|
||||
|
||||
Error err = mGralloc->set(importedHandle, gralloc4::MetadataType_Dataspace, metadata);
|
||||
if (err == Error::UNSUPPORTED) {
|
||||
GTEST_SUCCEED() << "setting this metadata is unsupported";
|
||||
return;
|
||||
}
|
||||
ASSERT_EQ(Error::NONE, err);
|
||||
}
|
||||
|
||||
Dataspace realSpace = Dataspace::UNKNOWN;
|
||||
{
|
||||
hidl_vec<uint8_t> metadata;
|
||||
ASSERT_EQ(Error::NONE,
|
||||
mGralloc->get(bufferHandle, gralloc4::MetadataType_Dataspace, &metadata));
|
||||
ASSERT_NO_FATAL_FAILURE(gralloc4::decodeDataspace(metadata, &realSpace));
|
||||
}
|
||||
|
||||
EXPECT_EQ(dataspace, realSpace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test IMapper::set(metadata) for constant metadata
|
||||
*/
|
||||
|
||||
@@ -151,8 +151,8 @@ interface IIdentityCredential {
|
||||
* IntentToRetain = bool
|
||||
*
|
||||
* For the readerSignature parameter, this can either be empty or if non-empty it
|
||||
* must be a COSE_Sign1 structure with an ECDSA signature over the content of the
|
||||
* CBOR conforming to the following CDDL:
|
||||
* must be a COSE_Sign1 where the payload is the bytes of the
|
||||
* ReaderAuthenticationBytes CBOR defined below:
|
||||
*
|
||||
* ReaderAuthentication = [
|
||||
* "ReaderAuthentication",
|
||||
@@ -160,16 +160,11 @@ interface IIdentityCredential {
|
||||
* ItemsRequestBytes
|
||||
* ]
|
||||
*
|
||||
* SessionTranscript = [
|
||||
* DeviceEngagementBytes,
|
||||
* EReaderKeyBytes
|
||||
* ]
|
||||
* SessionTranscript = any
|
||||
*
|
||||
* DeviceEngagementBytes = #6.24(bstr .cbor DeviceEngagement)
|
||||
* EReaderKeyBytes = #6.24(bstr .cbor EReaderKey.Pub)
|
||||
* ItemsRequestBytes = #6.24(bstr .cbor ItemsRequest)
|
||||
*
|
||||
* EReaderKey.Pub = COSE_Key ; Ephemeral public key provided by reader
|
||||
* ReaderAuthenticationBytes = #6.24(bstr .cbor ReaderAuthentication)
|
||||
*
|
||||
* The public key corresponding to the key used to made signature, can be found in the
|
||||
* 'x5chain' unprotected header element of the COSE_Sign1 structure (as as described
|
||||
@@ -184,8 +179,12 @@ interface IIdentityCredential {
|
||||
*
|
||||
* If the SessionTranscript CBOR is not empty, the X and Y coordinates of the public
|
||||
* part of the key-pair previously generated by createEphemeralKeyPair() must appear
|
||||
* somewhere in the bytes of DeviceEngagement structure. Both X and Y should be in
|
||||
* uncompressed form. If this is not satisfied, the call fails with
|
||||
* somewhere in the bytes of the CBOR. Each of these coordinates must appear encoded
|
||||
* with the most significant bits first and use the exact amount of bits indicated by
|
||||
* the key size of the ephemeral keys. For example, if the ephemeral key is using the
|
||||
* P-256 curve then the 32 bytes for the X coordinate encoded with the most significant
|
||||
* bits first must appear somewhere in the CBOR and ditto for the 32 bytes for the Y
|
||||
* coordinate. If this is not satisfied, the call fails with
|
||||
* STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND.
|
||||
*
|
||||
* @param accessControlProfiles
|
||||
@@ -281,7 +280,7 @@ interface IIdentityCredential {
|
||||
*
|
||||
* @param out mac is empty if signingKeyBlob or the sessionTranscript passed to
|
||||
* startRetrieval() is empty. Otherwise it is a COSE_Mac0 with empty payload
|
||||
* and the detached content is set to DeviceAuthentication as defined below.
|
||||
* and the detached content is set to DeviceAuthenticationBytes as defined below.
|
||||
* This code is produced by using the key agreement and key derivation function
|
||||
* from the ciphersuite with the authentication private key and the reader
|
||||
* ephemeral public key to compute a shared message authentication code (MAC)
|
||||
@@ -298,15 +297,12 @@ interface IIdentityCredential {
|
||||
*
|
||||
* DocType = tstr
|
||||
*
|
||||
* SessionTranscript = [
|
||||
* DeviceEngagementBytes,
|
||||
* EReaderKeyBytes
|
||||
* ]
|
||||
* SessionTranscript = any
|
||||
*
|
||||
* DeviceEngagementBytes = #6.24(bstr .cbor DeviceEngagement)
|
||||
* EReaderKeyBytes = #6.24(bstr .cbor EReaderKey.Pub)
|
||||
* DeviceNameSpacesBytes = #6.24(bstr .cbor DeviceNameSpaces)
|
||||
*
|
||||
* DeviceAuthenticationBytes = #6.24(bstr .cbor DeviceAuthentication)
|
||||
*
|
||||
* where
|
||||
*
|
||||
* DeviceNameSpaces = {
|
||||
@@ -356,8 +352,9 @@ interface IIdentityCredential {
|
||||
*
|
||||
* - subjectPublicKeyInfo: must contain attested public key.
|
||||
*
|
||||
* @param out signingKeyBlob contains an encrypted copy of the newly-generated private
|
||||
* signing key.
|
||||
* @param out signingKeyBlob contains an AES-GCM-ENC(storageKey, R, signingKey, docType)
|
||||
* where signingKey is an EC private key in uncompressed form. That is, the returned
|
||||
* blob is an encrypted copy of the newly-generated private signing key.
|
||||
*
|
||||
* @return an X.509 certificate for the new signing key, signed by the credential key.
|
||||
*/
|
||||
|
||||
@@ -99,7 +99,7 @@ import android.hardware.identity.CipherSuite;
|
||||
* Various fields need to be encoded as precisely-specified byte arrays. Where existing standards
|
||||
* define appropriate encodings, those are used. For example, X.509 certificates. Where new
|
||||
* encodings are needed, CBOR is used. CBOR maps are described in CDDL notation
|
||||
* (https://tools.ietf.org/html/draft-ietf-cbor-cddl-06).
|
||||
* (https://tools.ietf.org/html/rfc8610).
|
||||
*
|
||||
* All binder calls in the HAL may return a ServiceSpecificException with statuses from the
|
||||
* STATUS_* integers defined in this interface. Each method states which status can be returned
|
||||
|
||||
@@ -29,9 +29,27 @@ interface IWritableIdentityCredential {
|
||||
* Gets the certificate chain for credentialKey which can be used to prove the hardware
|
||||
* characteristics to an issuing authority. Must not be called more than once.
|
||||
*
|
||||
* The following non-optional fields for the X.509 certificate shall be set as follows:
|
||||
*
|
||||
* - version: INTEGER 2 (means v3 certificate).
|
||||
*
|
||||
* - serialNumber: INTEGER 1 (fixed value: same on all certs).
|
||||
*
|
||||
* - signature: must be set to ECDSA.
|
||||
*
|
||||
* - subject: CN shall be set to "Android Identity Credential Key".
|
||||
*
|
||||
* - issuer: shall be set to "credentialStoreName (credentialStoreAuthorName)" using the
|
||||
* values returned in HardwareInformation.
|
||||
*
|
||||
* - validity: should be from current time and expire at the same time as the
|
||||
* attestation batch certificate used.
|
||||
*
|
||||
* - subjectPublicKeyInfo: must contain attested public key.
|
||||
*
|
||||
* The certificate chain must be generated using Keymaster Attestation
|
||||
* (see https://source.android.com/security/keystore/attestation) with the
|
||||
* following additional requirements:
|
||||
* following additional requirements on the data in the attestation extension:
|
||||
*
|
||||
* - The attestationVersion field in the attestation extension must be at least 3.
|
||||
*
|
||||
@@ -109,7 +127,8 @@ interface IWritableIdentityCredential {
|
||||
* in Tag::ATTESTATION_APPLICATION_ID. This schema is described in
|
||||
* https://developer.android.com/training/articles/security-key-attestation#certificate_schema_attestationid
|
||||
*
|
||||
* @param attestationChallenge a challenge set by the issuer to ensure freshness.
|
||||
* @param attestationChallenge a challenge set by the issuer to ensure freshness. If
|
||||
* this is empty, the call fails with STATUS_INVALID_DATA.
|
||||
*
|
||||
* @return the X.509 certificate chain for the credentialKey
|
||||
*/
|
||||
@@ -250,6 +269,7 @@ interface IWritableIdentityCredential {
|
||||
* CredentialKeys = [
|
||||
* bstr, ; storageKey, a 128-bit AES key
|
||||
* bstr ; credentialPrivKey, the private key for credentialKey
|
||||
* ; in uncompressed form
|
||||
* ]
|
||||
*
|
||||
* @param out proofOfProvisioningSignature proves to the IA that the credential was imported
|
||||
|
||||
@@ -39,6 +39,10 @@ using ::std::optional;
|
||||
using namespace ::android::hardware::identity;
|
||||
|
||||
int IdentityCredential::initialize() {
|
||||
if (credentialData_.size() == 0) {
|
||||
LOG(ERROR) << "CredentialData is empty";
|
||||
return IIdentityCredentialStore::STATUS_INVALID_DATA;
|
||||
}
|
||||
auto [item, _, message] = cppbor::parse(credentialData_);
|
||||
if (item == nullptr) {
|
||||
LOG(ERROR) << "CredentialData is not valid CBOR: " << message;
|
||||
@@ -164,6 +168,7 @@ ndk::ScopedAStatus IdentityCredential::createAuthChallenge(int64_t* outChallenge
|
||||
}
|
||||
|
||||
*outChallenge = challenge;
|
||||
authChallenge_ = challenge;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
@@ -223,7 +228,8 @@ bool checkUserAuthentication(const SecureAccessControlProfile& profile,
|
||||
}
|
||||
|
||||
if (authToken.challenge != int64_t(authChallenge)) {
|
||||
LOG(ERROR) << "Challenge in authToken doesn't match the challenge we created";
|
||||
LOG(ERROR) << "Challenge in authToken (" << uint64_t(authToken.challenge) << ") "
|
||||
<< "doesn't match the challenge we created (" << authChallenge << ")";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -314,13 +320,16 @@ ndk::ScopedAStatus IdentityCredential::startRetrieval(
|
||||
}
|
||||
|
||||
const vector<uint8_t>& itemsRequestBytes = itemsRequest;
|
||||
vector<uint8_t> dataThatWasSigned = cppbor::Array()
|
||||
.add("ReaderAuthentication")
|
||||
.add(sessionTranscriptItem_->clone())
|
||||
.add(cppbor::Semantic(24, itemsRequestBytes))
|
||||
.encode();
|
||||
vector<uint8_t> encodedReaderAuthentication =
|
||||
cppbor::Array()
|
||||
.add("ReaderAuthentication")
|
||||
.add(sessionTranscriptItem_->clone())
|
||||
.add(cppbor::Semantic(24, itemsRequestBytes))
|
||||
.encode();
|
||||
vector<uint8_t> encodedReaderAuthenticationBytes =
|
||||
cppbor::Semantic(24, encodedReaderAuthentication).encode();
|
||||
if (!support::coseCheckEcDsaSignature(readerSignature,
|
||||
dataThatWasSigned, // detached content
|
||||
encodedReaderAuthenticationBytes, // detached content
|
||||
readerPublicKey.value())) {
|
||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||
IIdentityCredentialStore::STATUS_READER_SIGNATURE_CHECK_FAILED,
|
||||
@@ -341,28 +350,6 @@ ndk::ScopedAStatus IdentityCredential::startRetrieval(
|
||||
//
|
||||
// We do this by just searching for the X and Y coordinates.
|
||||
if (sessionTranscript.size() > 0) {
|
||||
const cppbor::Array* array = sessionTranscriptItem_->asArray();
|
||||
if (array == nullptr || array->size() != 2) {
|
||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||
IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND,
|
||||
"SessionTranscript is not an array with two items"));
|
||||
}
|
||||
const cppbor::Semantic* taggedEncodedDE = (*array)[0]->asSemantic();
|
||||
if (taggedEncodedDE == nullptr || taggedEncodedDE->value() != 24) {
|
||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||
IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND,
|
||||
"First item in SessionTranscript array is not a "
|
||||
"semantic with value 24"));
|
||||
}
|
||||
const cppbor::Bstr* encodedDE = (taggedEncodedDE->child())->asBstr();
|
||||
if (encodedDE == nullptr) {
|
||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||
IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND,
|
||||
"Child of semantic in first item in SessionTranscript "
|
||||
"array is not a bstr"));
|
||||
}
|
||||
const vector<uint8_t>& bytesDE = encodedDE->value();
|
||||
|
||||
auto [getXYSuccess, ePubX, ePubY] = support::ecPublicKeyGetXandY(ephemeralPublicKey_);
|
||||
if (!getXYSuccess) {
|
||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||
@@ -370,8 +357,10 @@ ndk::ScopedAStatus IdentityCredential::startRetrieval(
|
||||
"Error extracting X and Y from ePub"));
|
||||
}
|
||||
if (sessionTranscript.size() > 0 &&
|
||||
!(memmem(bytesDE.data(), bytesDE.size(), ePubX.data(), ePubX.size()) != nullptr &&
|
||||
memmem(bytesDE.data(), bytesDE.size(), ePubY.data(), ePubY.size()) != nullptr)) {
|
||||
!(memmem(sessionTranscript.data(), sessionTranscript.size(), ePubX.data(),
|
||||
ePubX.size()) != nullptr &&
|
||||
memmem(sessionTranscript.data(), sessionTranscript.size(), ePubY.data(),
|
||||
ePubY.size()) != nullptr)) {
|
||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||
IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND,
|
||||
"Did not find ephemeral public key's X and Y coordinates in "
|
||||
@@ -478,9 +467,10 @@ ndk::ScopedAStatus IdentityCredential::startRetrieval(
|
||||
}
|
||||
|
||||
// Validate all the access control profiles in the requestData.
|
||||
bool haveAuthToken = (authToken.mac.size() > 0);
|
||||
bool haveAuthToken = (authToken.timestamp.milliSeconds != int64_t(0));
|
||||
for (const auto& profile : accessControlProfiles) {
|
||||
if (!secureAccessControlProfileCheckMac(profile, storageKey_)) {
|
||||
LOG(ERROR) << "Error checking MAC for profile";
|
||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||
IIdentityCredentialStore::STATUS_INVALID_DATA,
|
||||
"Error checking MAC for profile"));
|
||||
@@ -796,7 +786,7 @@ ndk::ScopedAStatus IdentityCredential::finishRetrieval(vector<int8_t>* outMac,
|
||||
array.add(sessionTranscriptItem_->clone());
|
||||
array.add(docType_);
|
||||
array.add(cppbor::Semantic(24, encodedDeviceNameSpaces));
|
||||
vector<uint8_t> encodedDeviceAuthentication = array.encode();
|
||||
vector<uint8_t> deviceAuthenticationBytes = cppbor::Semantic(24, array.encode()).encode();
|
||||
|
||||
vector<uint8_t> docTypeAsBlob(docType_.begin(), docType_.end());
|
||||
optional<vector<uint8_t>> signingKey =
|
||||
@@ -814,17 +804,24 @@ ndk::ScopedAStatus IdentityCredential::finishRetrieval(vector<int8_t>* outMac,
|
||||
IIdentityCredentialStore::STATUS_FAILED, "Error doing ECDH"));
|
||||
}
|
||||
|
||||
// Mix-in SessionTranscriptBytes
|
||||
vector<uint8_t> sessionTranscriptBytes = cppbor::Semantic(24, sessionTranscript_).encode();
|
||||
vector<uint8_t> sharedSecretWithSessionTranscriptBytes = sharedSecret.value();
|
||||
std::copy(sessionTranscriptBytes.begin(), sessionTranscriptBytes.end(),
|
||||
std::back_inserter(sharedSecretWithSessionTranscriptBytes));
|
||||
|
||||
vector<uint8_t> salt = {0x00};
|
||||
vector<uint8_t> info = {};
|
||||
optional<vector<uint8_t>> derivedKey = support::hkdf(sharedSecret.value(), salt, info, 32);
|
||||
optional<vector<uint8_t>> derivedKey =
|
||||
support::hkdf(sharedSecretWithSessionTranscriptBytes, salt, info, 32);
|
||||
if (!derivedKey) {
|
||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||
IIdentityCredentialStore::STATUS_FAILED,
|
||||
"Error deriving key from shared secret"));
|
||||
}
|
||||
|
||||
mac = support::coseMac0(derivedKey.value(), {}, // payload
|
||||
encodedDeviceAuthentication); // additionalData
|
||||
mac = support::coseMac0(derivedKey.value(), {}, // payload
|
||||
deviceAuthenticationBytes); // detached content
|
||||
if (!mac) {
|
||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||
IIdentityCredentialStore::STATUS_FAILED, "Error MACing data"));
|
||||
|
||||
@@ -65,6 +65,10 @@ ndk::ScopedAStatus WritableIdentityCredential::getAttestationCertificate(
|
||||
IIdentityCredentialStore::STATUS_FAILED,
|
||||
"Error attestation certificate previously generated"));
|
||||
}
|
||||
if (attestationChallenge.empty()) {
|
||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||
IIdentityCredentialStore::STATUS_INVALID_DATA, "Challenge can not be empty"));
|
||||
}
|
||||
|
||||
vector<uint8_t> challenge(attestationChallenge.begin(), attestationChallenge.end());
|
||||
vector<uint8_t> appId(attestationApplicationId.begin(), attestationApplicationId.end());
|
||||
@@ -165,6 +169,13 @@ ndk::ScopedAStatus WritableIdentityCredential::addAccessControlProfile(
|
||||
"userAuthenticationRequired is false but timeout is non-zero"));
|
||||
}
|
||||
|
||||
// If |userAuthenticationRequired| is true, then |secureUserId| must be non-zero.
|
||||
if (userAuthenticationRequired && secureUserId == 0) {
|
||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||
IIdentityCredentialStore::STATUS_INVALID_DATA,
|
||||
"userAuthenticationRequired is true but secureUserId is zero"));
|
||||
}
|
||||
|
||||
profile.id = id;
|
||||
profile.readerCertificate = readerCertificate;
|
||||
profile.userAuthenticationRequired = userAuthenticationRequired;
|
||||
|
||||
@@ -10,20 +10,23 @@ cc_test {
|
||||
"VtsIdentityTestUtils.cpp",
|
||||
"VtsAttestationTests.cpp",
|
||||
"VtsAttestationParserSupport.cpp",
|
||||
"UserAuthTests.cpp",
|
||||
"ReaderAuthTests.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"android.hardware.keymaster@4.0",
|
||||
"libbinder",
|
||||
"libcrypto",
|
||||
"libkeymaster_portable",
|
||||
"libsoft_attestation_cert",
|
||||
"libpuresoftkeymasterdevice",
|
||||
],
|
||||
static_libs: [
|
||||
"libcppbor",
|
||||
"libkeymaster_portable",
|
||||
"libsoft_attestation_cert",
|
||||
"libpuresoftkeymasterdevice",
|
||||
"android.hardware.keymaster@4.0",
|
||||
"android.hardware.identity-support-lib",
|
||||
"android.hardware.identity-cpp",
|
||||
"android.hardware.keymaster-cpp",
|
||||
"android.hardware.keymaster-ndk_platform",
|
||||
],
|
||||
test_suites: [
|
||||
"general-tests",
|
||||
|
||||
602
identity/aidl/vts/ReaderAuthTests.cpp
Normal file
602
identity/aidl/vts/ReaderAuthTests.cpp
Normal file
@@ -0,0 +1,602 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "ReaderAuthTests"
|
||||
|
||||
#include <aidl/Gtest.h>
|
||||
#include <aidl/Vintf.h>
|
||||
#include <aidl/android/hardware/keymaster/HardwareAuthToken.h>
|
||||
#include <aidl/android/hardware/keymaster/VerificationToken.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android/hardware/identity/IIdentityCredentialStore.h>
|
||||
#include <android/hardware/identity/support/IdentityCredentialSupport.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <binder/ProcessState.h>
|
||||
#include <cppbor.h>
|
||||
#include <cppbor_parse.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <future>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
#include "VtsIdentityTestUtils.h"
|
||||
|
||||
namespace android::hardware::identity {
|
||||
|
||||
using std::endl;
|
||||
using std::make_pair;
|
||||
using std::map;
|
||||
using std::optional;
|
||||
using std::pair;
|
||||
using std::string;
|
||||
using std::tie;
|
||||
using std::vector;
|
||||
|
||||
using ::android::sp;
|
||||
using ::android::String16;
|
||||
using ::android::binder::Status;
|
||||
|
||||
using ::android::hardware::keymaster::HardwareAuthToken;
|
||||
using ::android::hardware::keymaster::VerificationToken;
|
||||
|
||||
class ReaderAuthTests : public testing::TestWithParam<string> {
|
||||
public:
|
||||
virtual void SetUp() override {
|
||||
credentialStore_ = android::waitForDeclaredService<IIdentityCredentialStore>(
|
||||
String16(GetParam().c_str()));
|
||||
ASSERT_NE(credentialStore_, nullptr);
|
||||
}
|
||||
|
||||
void provisionData();
|
||||
void retrieveData(const vector<uint8_t>& readerPrivateKey,
|
||||
const vector<vector<uint8_t>>& readerCertChain, bool expectSuccess,
|
||||
bool leaveOutAccessibleToAllFromRequestMessage);
|
||||
|
||||
// Set by provisionData
|
||||
vector<uint8_t> readerPublicKey_;
|
||||
vector<uint8_t> readerPrivateKey_;
|
||||
vector<uint8_t> intermediateAPublicKey_;
|
||||
vector<uint8_t> intermediateAPrivateKey_;
|
||||
vector<uint8_t> intermediateBPublicKey_;
|
||||
vector<uint8_t> intermediateBPrivateKey_;
|
||||
vector<uint8_t> intermediateCPublicKey_;
|
||||
vector<uint8_t> intermediateCPrivateKey_;
|
||||
|
||||
vector<uint8_t> cert_A_SelfSigned_;
|
||||
|
||||
vector<uint8_t> cert_B_SelfSigned_;
|
||||
|
||||
vector<uint8_t> cert_B_SignedBy_C_;
|
||||
|
||||
vector<uint8_t> cert_C_SelfSigned_;
|
||||
|
||||
vector<uint8_t> cert_reader_SelfSigned_;
|
||||
vector<uint8_t> cert_reader_SignedBy_A_;
|
||||
vector<uint8_t> cert_reader_SignedBy_B_;
|
||||
|
||||
SecureAccessControlProfile sacp0_;
|
||||
SecureAccessControlProfile sacp1_;
|
||||
SecureAccessControlProfile sacp2_;
|
||||
SecureAccessControlProfile sacp3_;
|
||||
|
||||
vector<uint8_t> encContentAccessibleByA_;
|
||||
vector<uint8_t> encContentAccessibleByAorB_;
|
||||
vector<uint8_t> encContentAccessibleByB_;
|
||||
vector<uint8_t> encContentAccessibleByC_;
|
||||
vector<uint8_t> encContentAccessibleByAll_;
|
||||
vector<uint8_t> encContentAccessibleByNone_;
|
||||
|
||||
vector<uint8_t> credentialData_;
|
||||
|
||||
// Set by retrieveData()
|
||||
bool canGetAccessibleByA_;
|
||||
bool canGetAccessibleByAorB_;
|
||||
bool canGetAccessibleByB_;
|
||||
bool canGetAccessibleByC_;
|
||||
bool canGetAccessibleByAll_;
|
||||
bool canGetAccessibleByNone_;
|
||||
|
||||
sp<IIdentityCredentialStore> credentialStore_;
|
||||
};
|
||||
|
||||
pair<vector<uint8_t>, vector<uint8_t>> generateReaderKey() {
|
||||
optional<vector<uint8_t>> keyPKCS8 = support::createEcKeyPair();
|
||||
optional<vector<uint8_t>> publicKey = support::ecKeyPairGetPublicKey(keyPKCS8.value());
|
||||
optional<vector<uint8_t>> privateKey = support::ecKeyPairGetPrivateKey(keyPKCS8.value());
|
||||
return make_pair(publicKey.value(), privateKey.value());
|
||||
}
|
||||
|
||||
vector<uint8_t> generateReaderCert(const vector<uint8_t>& publicKey,
|
||||
const vector<uint8_t>& signingKey) {
|
||||
time_t validityNotBefore = 0;
|
||||
time_t validityNotAfter = 0xffffffff;
|
||||
optional<vector<uint8_t>> cert =
|
||||
support::ecPublicKeyGenerateCertificate(publicKey, signingKey, "24601", "Issuer",
|
||||
"Subject", validityNotBefore, validityNotAfter);
|
||||
return cert.value();
|
||||
}
|
||||
|
||||
void ReaderAuthTests::provisionData() {
|
||||
// Keys and certificates for intermediates.
|
||||
tie(intermediateAPublicKey_, intermediateAPrivateKey_) = generateReaderKey();
|
||||
tie(intermediateBPublicKey_, intermediateBPrivateKey_) = generateReaderKey();
|
||||
tie(intermediateCPublicKey_, intermediateCPrivateKey_) = generateReaderKey();
|
||||
|
||||
cert_A_SelfSigned_ = generateReaderCert(intermediateAPublicKey_, intermediateAPrivateKey_);
|
||||
|
||||
cert_B_SelfSigned_ = generateReaderCert(intermediateBPublicKey_, intermediateBPrivateKey_);
|
||||
|
||||
cert_B_SignedBy_C_ = generateReaderCert(intermediateBPublicKey_, intermediateCPrivateKey_);
|
||||
|
||||
cert_C_SelfSigned_ = generateReaderCert(intermediateCPublicKey_, intermediateCPrivateKey_);
|
||||
|
||||
// Key and self-signed certificate reader
|
||||
tie(readerPublicKey_, readerPrivateKey_) = generateReaderKey();
|
||||
cert_reader_SelfSigned_ = generateReaderCert(readerPublicKey_, readerPrivateKey_);
|
||||
|
||||
// Certificate for reader signed by intermediates
|
||||
cert_reader_SignedBy_A_ = generateReaderCert(readerPublicKey_, intermediateAPrivateKey_);
|
||||
cert_reader_SignedBy_B_ = generateReaderCert(readerPublicKey_, intermediateBPrivateKey_);
|
||||
|
||||
string docType = "org.iso.18013-5.2019.mdl";
|
||||
bool testCredential = true;
|
||||
sp<IWritableIdentityCredential> wc;
|
||||
ASSERT_TRUE(credentialStore_->createCredential(docType, testCredential, &wc).isOk());
|
||||
|
||||
vector<uint8_t> attestationApplicationId = {};
|
||||
vector<uint8_t> attestationChallenge = {1};
|
||||
vector<Certificate> certChain;
|
||||
ASSERT_TRUE(wc->getAttestationCertificate(attestationApplicationId, attestationChallenge,
|
||||
&certChain)
|
||||
.isOk());
|
||||
|
||||
size_t proofOfProvisioningSize =
|
||||
465 + cert_A_SelfSigned_.size() + cert_B_SelfSigned_.size() + cert_C_SelfSigned_.size();
|
||||
ASSERT_TRUE(wc->setExpectedProofOfProvisioningSize(proofOfProvisioningSize).isOk());
|
||||
|
||||
// Not in v1 HAL, may fail
|
||||
wc->startPersonalization(4 /* numAccessControlProfiles */,
|
||||
{6} /* numDataElementsPerNamespace */);
|
||||
|
||||
// AIDL expects certificates wrapped in the Certificate type...
|
||||
Certificate cert_A;
|
||||
Certificate cert_B;
|
||||
Certificate cert_C;
|
||||
cert_A.encodedCertificate = cert_A_SelfSigned_;
|
||||
cert_B.encodedCertificate = cert_B_SelfSigned_;
|
||||
cert_C.encodedCertificate = cert_C_SelfSigned_;
|
||||
|
||||
// Access control profile 0: accessible by A
|
||||
ASSERT_TRUE(wc->addAccessControlProfile(0, cert_A, false, 0, 0, &sacp0_).isOk());
|
||||
|
||||
// Access control profile 1: accessible by B
|
||||
ASSERT_TRUE(wc->addAccessControlProfile(1, cert_B, false, 0, 0, &sacp1_).isOk());
|
||||
|
||||
// Access control profile 2: accessible by C
|
||||
ASSERT_TRUE(wc->addAccessControlProfile(2, cert_C, false, 0, 0, &sacp2_).isOk());
|
||||
|
||||
// Access control profile 3: open access
|
||||
ASSERT_TRUE(wc->addAccessControlProfile(3, {}, false, 0, 0, &sacp3_).isOk());
|
||||
|
||||
// Data Element: "Accessible by A"
|
||||
ASSERT_TRUE(wc->beginAddEntry({0}, "ns", "Accessible by A", 1).isOk());
|
||||
ASSERT_TRUE(wc->addEntryValue({9}, &encContentAccessibleByA_).isOk());
|
||||
|
||||
// Data Element: "Accessible by A or B"
|
||||
ASSERT_TRUE(wc->beginAddEntry({0, 1}, "ns", "Accessible by A or B", 1).isOk());
|
||||
ASSERT_TRUE(wc->addEntryValue({9}, &encContentAccessibleByAorB_).isOk());
|
||||
|
||||
// Data Element: "Accessible by B"
|
||||
ASSERT_TRUE(wc->beginAddEntry({1}, "ns", "Accessible by B", 1).isOk());
|
||||
ASSERT_TRUE(wc->addEntryValue({9}, &encContentAccessibleByB_).isOk());
|
||||
|
||||
// Data Element: "Accessible by C"
|
||||
ASSERT_TRUE(wc->beginAddEntry({2}, "ns", "Accessible by C", 1).isOk());
|
||||
ASSERT_TRUE(wc->addEntryValue({9}, &encContentAccessibleByC_).isOk());
|
||||
|
||||
// Data Element: "Accessible by All"
|
||||
ASSERT_TRUE(wc->beginAddEntry({3}, "ns", "Accessible by All", 1).isOk());
|
||||
ASSERT_TRUE(wc->addEntryValue({9}, &encContentAccessibleByAll_).isOk());
|
||||
|
||||
// Data Element: "Accessible by None"
|
||||
ASSERT_TRUE(wc->beginAddEntry({}, "ns", "Accessible by None", 1).isOk());
|
||||
ASSERT_TRUE(wc->addEntryValue({9}, &encContentAccessibleByNone_).isOk());
|
||||
|
||||
vector<uint8_t> proofOfProvisioningSignature;
|
||||
ASSERT_TRUE(wc->finishAddingEntries(&credentialData_, &proofOfProvisioningSignature).isOk());
|
||||
}
|
||||
|
||||
RequestDataItem buildRequestDataItem(const string& name, size_t size,
|
||||
vector<int32_t> accessControlProfileIds) {
|
||||
RequestDataItem item;
|
||||
item.name = name;
|
||||
item.size = size;
|
||||
item.accessControlProfileIds = accessControlProfileIds;
|
||||
return item;
|
||||
}
|
||||
|
||||
void ReaderAuthTests::retrieveData(const vector<uint8_t>& readerPrivateKey,
|
||||
const vector<vector<uint8_t>>& readerCertChain,
|
||||
bool expectSuccess,
|
||||
bool leaveOutAccessibleToAllFromRequestMessage) {
|
||||
canGetAccessibleByA_ = false;
|
||||
canGetAccessibleByAorB_ = false;
|
||||
canGetAccessibleByB_ = false;
|
||||
canGetAccessibleByC_ = false;
|
||||
canGetAccessibleByAll_ = false;
|
||||
canGetAccessibleByNone_ = false;
|
||||
|
||||
sp<IIdentityCredential> c;
|
||||
ASSERT_TRUE(credentialStore_
|
||||
->getCredential(
|
||||
CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256,
|
||||
credentialData_, &c)
|
||||
.isOk());
|
||||
|
||||
optional<vector<uint8_t>> readerEKeyPair = support::createEcKeyPair();
|
||||
optional<vector<uint8_t>> readerEPublicKey =
|
||||
support::ecKeyPairGetPublicKey(readerEKeyPair.value());
|
||||
ASSERT_TRUE(c->setReaderEphemeralPublicKey(readerEPublicKey.value()).isOk());
|
||||
|
||||
vector<uint8_t> eKeyPair;
|
||||
ASSERT_TRUE(c->createEphemeralKeyPair(&eKeyPair).isOk());
|
||||
optional<vector<uint8_t>> ePublicKey = support::ecKeyPairGetPublicKey(eKeyPair);
|
||||
|
||||
// Calculate requestData field and sign it with the reader key.
|
||||
auto [getXYSuccess, ephX, ephY] = support::ecPublicKeyGetXandY(ePublicKey.value());
|
||||
ASSERT_TRUE(getXYSuccess);
|
||||
cppbor::Map deviceEngagement = cppbor::Map().add("ephX", ephX).add("ephY", ephY);
|
||||
vector<uint8_t> deviceEngagementBytes = deviceEngagement.encode();
|
||||
vector<uint8_t> eReaderPubBytes = cppbor::Tstr("ignored").encode();
|
||||
cppbor::Array sessionTranscript = cppbor::Array()
|
||||
.add(cppbor::Semantic(24, deviceEngagementBytes))
|
||||
.add(cppbor::Semantic(24, eReaderPubBytes));
|
||||
vector<uint8_t> sessionTranscriptBytes = sessionTranscript.encode();
|
||||
|
||||
vector<uint8_t> itemsRequestBytes;
|
||||
if (leaveOutAccessibleToAllFromRequestMessage) {
|
||||
itemsRequestBytes =
|
||||
cppbor::Map("nameSpaces",
|
||||
cppbor::Map().add("ns", cppbor::Map()
|
||||
.add("Accessible by A", false)
|
||||
.add("Accessible by A or B", false)
|
||||
.add("Accessible by B", false)
|
||||
.add("Accessible by C", false)
|
||||
.add("Accessible by None", false)))
|
||||
.encode();
|
||||
} else {
|
||||
itemsRequestBytes =
|
||||
cppbor::Map("nameSpaces",
|
||||
cppbor::Map().add("ns", cppbor::Map()
|
||||
.add("Accessible by A", false)
|
||||
.add("Accessible by A or B", false)
|
||||
.add("Accessible by B", false)
|
||||
.add("Accessible by C", false)
|
||||
.add("Accessible by All", false)
|
||||
.add("Accessible by None", false)))
|
||||
.encode();
|
||||
}
|
||||
vector<uint8_t> encodedReaderAuthentication =
|
||||
cppbor::Array()
|
||||
.add("ReaderAuthentication")
|
||||
.add(sessionTranscript.clone())
|
||||
.add(cppbor::Semantic(24, itemsRequestBytes))
|
||||
.encode();
|
||||
vector<uint8_t> encodedReaderAuthenticationBytes =
|
||||
cppbor::Semantic(24, encodedReaderAuthentication).encode();
|
||||
|
||||
optional<vector<uint8_t>> readerSignature =
|
||||
support::coseSignEcDsa(readerPrivateKey, // private key for reader
|
||||
{}, // content
|
||||
encodedReaderAuthenticationBytes, // detached content
|
||||
support::certificateChainJoin(readerCertChain));
|
||||
ASSERT_TRUE(readerSignature);
|
||||
|
||||
// Generate the key that will be used to sign AuthenticatedData.
|
||||
vector<uint8_t> signingKeyBlob;
|
||||
Certificate signingKeyCertificate;
|
||||
ASSERT_TRUE(c->generateSigningKeyPair(&signingKeyBlob, &signingKeyCertificate).isOk());
|
||||
|
||||
RequestNamespace rns;
|
||||
rns.namespaceName = "ns";
|
||||
rns.items.push_back(buildRequestDataItem("Accessible by A", 1, {0}));
|
||||
rns.items.push_back(buildRequestDataItem("Accessible by A or B", 1, {0, 1}));
|
||||
rns.items.push_back(buildRequestDataItem("Accessible by B", 1, {1}));
|
||||
rns.items.push_back(buildRequestDataItem("Accessible by C", 1, {2}));
|
||||
rns.items.push_back(buildRequestDataItem("Accessible by All", 1, {3}));
|
||||
rns.items.push_back(buildRequestDataItem("Accessible by None", 1, {}));
|
||||
// OK to fail, not available in v1 HAL
|
||||
c->setRequestedNamespaces({rns}).isOk();
|
||||
|
||||
// It doesn't matter since no user auth is needed in this particular test,
|
||||
// but for good measure, clear out the tokens we pass to the HAL.
|
||||
HardwareAuthToken authToken;
|
||||
VerificationToken verificationToken;
|
||||
authToken.challenge = 0;
|
||||
authToken.userId = 0;
|
||||
authToken.authenticatorId = 0;
|
||||
authToken.authenticatorType = ::android::hardware::keymaster::HardwareAuthenticatorType::NONE;
|
||||
authToken.timestamp.milliSeconds = 0;
|
||||
authToken.mac.clear();
|
||||
verificationToken.challenge = 0;
|
||||
verificationToken.timestamp.milliSeconds = 0;
|
||||
verificationToken.securityLevel = ::android::hardware::keymaster::SecurityLevel::SOFTWARE;
|
||||
verificationToken.mac.clear();
|
||||
// OK to fail, not available in v1 HAL
|
||||
c->setVerificationToken(verificationToken);
|
||||
|
||||
Status status = c->startRetrieval(
|
||||
{sacp0_, sacp1_, sacp2_, sacp3_}, authToken, itemsRequestBytes, signingKeyBlob,
|
||||
sessionTranscriptBytes, readerSignature.value(), {6 /* numDataElementsPerNamespace */});
|
||||
if (expectSuccess) {
|
||||
ASSERT_TRUE(status.isOk());
|
||||
} else {
|
||||
ASSERT_FALSE(status.isOk());
|
||||
return;
|
||||
}
|
||||
|
||||
vector<uint8_t> decrypted;
|
||||
|
||||
status = c->startRetrieveEntryValue("ns", "Accessible by A", 1, {0});
|
||||
if (status.isOk()) {
|
||||
canGetAccessibleByA_ = true;
|
||||
ASSERT_TRUE(c->retrieveEntryValue(encContentAccessibleByA_, &decrypted).isOk());
|
||||
}
|
||||
|
||||
status = c->startRetrieveEntryValue("ns", "Accessible by A or B", 1, {0, 1});
|
||||
if (status.isOk()) {
|
||||
canGetAccessibleByAorB_ = true;
|
||||
ASSERT_TRUE(c->retrieveEntryValue(encContentAccessibleByAorB_, &decrypted).isOk());
|
||||
}
|
||||
|
||||
status = c->startRetrieveEntryValue("ns", "Accessible by B", 1, {1});
|
||||
if (status.isOk()) {
|
||||
canGetAccessibleByB_ = true;
|
||||
ASSERT_TRUE(c->retrieveEntryValue(encContentAccessibleByB_, &decrypted).isOk());
|
||||
}
|
||||
|
||||
status = c->startRetrieveEntryValue("ns", "Accessible by C", 1, {2});
|
||||
if (status.isOk()) {
|
||||
canGetAccessibleByC_ = true;
|
||||
ASSERT_TRUE(c->retrieveEntryValue(encContentAccessibleByC_, &decrypted).isOk());
|
||||
}
|
||||
|
||||
status = c->startRetrieveEntryValue("ns", "Accessible by All", 1, {3});
|
||||
if (status.isOk()) {
|
||||
canGetAccessibleByAll_ = true;
|
||||
ASSERT_TRUE(c->retrieveEntryValue(encContentAccessibleByAll_, &decrypted).isOk());
|
||||
}
|
||||
|
||||
status = c->startRetrieveEntryValue("ns", "Accessible by None", 1, {});
|
||||
if (status.isOk()) {
|
||||
canGetAccessibleByNone_ = true;
|
||||
ASSERT_TRUE(c->retrieveEntryValue(encContentAccessibleByNone_, &decrypted).isOk());
|
||||
}
|
||||
|
||||
vector<uint8_t> mac;
|
||||
vector<uint8_t> deviceNameSpaces;
|
||||
ASSERT_TRUE(c->finishRetrieval(&mac, &deviceNameSpaces).isOk());
|
||||
}
|
||||
|
||||
TEST_P(ReaderAuthTests, presentingChain_Reader) {
|
||||
provisionData();
|
||||
retrieveData(readerPrivateKey_, {cert_reader_SelfSigned_}, true /* expectSuccess */,
|
||||
false /* leaveOutAccessibleToAllFromRequestMessage */);
|
||||
EXPECT_FALSE(canGetAccessibleByA_);
|
||||
EXPECT_FALSE(canGetAccessibleByAorB_);
|
||||
EXPECT_FALSE(canGetAccessibleByB_);
|
||||
EXPECT_FALSE(canGetAccessibleByC_);
|
||||
EXPECT_TRUE(canGetAccessibleByAll_);
|
||||
EXPECT_FALSE(canGetAccessibleByNone_);
|
||||
}
|
||||
|
||||
TEST_P(ReaderAuthTests, presentingChain_Reader_A) {
|
||||
provisionData();
|
||||
retrieveData(readerPrivateKey_, {cert_reader_SignedBy_A_, cert_A_SelfSigned_},
|
||||
true /* expectSuccess */, false /* leaveOutAccessibleToAllFromRequestMessage */);
|
||||
EXPECT_TRUE(canGetAccessibleByA_);
|
||||
EXPECT_TRUE(canGetAccessibleByAorB_);
|
||||
EXPECT_FALSE(canGetAccessibleByB_);
|
||||
EXPECT_FALSE(canGetAccessibleByC_);
|
||||
EXPECT_TRUE(canGetAccessibleByAll_);
|
||||
EXPECT_FALSE(canGetAccessibleByNone_);
|
||||
}
|
||||
|
||||
TEST_P(ReaderAuthTests, presentingChain_Reader_B) {
|
||||
provisionData();
|
||||
retrieveData(readerPrivateKey_, {cert_reader_SignedBy_B_, cert_B_SelfSigned_},
|
||||
true /* expectSuccess */, false /* leaveOutAccessibleToAllFromRequestMessage */);
|
||||
EXPECT_FALSE(canGetAccessibleByA_);
|
||||
EXPECT_TRUE(canGetAccessibleByAorB_);
|
||||
EXPECT_TRUE(canGetAccessibleByB_);
|
||||
EXPECT_FALSE(canGetAccessibleByC_);
|
||||
EXPECT_TRUE(canGetAccessibleByAll_);
|
||||
EXPECT_FALSE(canGetAccessibleByNone_);
|
||||
}
|
||||
|
||||
// This test proves that for the purpose of determining inclusion of an ACP certificate
|
||||
// in a presented reader chain, certificate equality is done by comparing public keys,
|
||||
// not bitwise comparison of the certificates.
|
||||
//
|
||||
// Specifically for this test, the ACP is configured with cert_B_SelfSigned_ and the
|
||||
// reader is presenting cert_B_SignedBy_C_. Both certificates have the same public
|
||||
// key - intermediateBPublicKey_ - but they are signed by different keys.
|
||||
//
|
||||
TEST_P(ReaderAuthTests, presentingChain_Reader_B_C) {
|
||||
provisionData();
|
||||
retrieveData(readerPrivateKey_,
|
||||
{cert_reader_SignedBy_B_, cert_B_SignedBy_C_, cert_C_SelfSigned_},
|
||||
true /* expectSuccess */, false /* leaveOutAccessibleToAllFromRequestMessage */);
|
||||
EXPECT_FALSE(canGetAccessibleByA_);
|
||||
EXPECT_TRUE(canGetAccessibleByAorB_);
|
||||
EXPECT_TRUE(canGetAccessibleByB_);
|
||||
EXPECT_TRUE(canGetAccessibleByC_);
|
||||
EXPECT_TRUE(canGetAccessibleByAll_);
|
||||
EXPECT_FALSE(canGetAccessibleByNone_);
|
||||
}
|
||||
|
||||
// This test presents a reader chain where the chain is invalid because
|
||||
// the 2nd certificate in the chain isn't signed by the 3rd one.
|
||||
//
|
||||
TEST_P(ReaderAuthTests, presentingInvalidChain) {
|
||||
provisionData();
|
||||
retrieveData(readerPrivateKey_,
|
||||
{cert_reader_SignedBy_B_, cert_B_SelfSigned_, cert_C_SelfSigned_},
|
||||
false /* expectSuccess */, false /* leaveOutAccessibleToAllFromRequestMessage */);
|
||||
}
|
||||
|
||||
// This tests presents a valid reader chain but where requestMessage isn't
|
||||
// signed by the private key corresponding to the public key in the top-level
|
||||
// certificate.
|
||||
//
|
||||
TEST_P(ReaderAuthTests, presentingMessageSignedNotByTopLevel) {
|
||||
provisionData();
|
||||
retrieveData(intermediateBPrivateKey_,
|
||||
{cert_reader_SignedBy_B_, cert_B_SignedBy_C_, cert_C_SelfSigned_},
|
||||
false /* expectSuccess */, false /* leaveOutAccessibleToAllFromRequestMessage */);
|
||||
}
|
||||
|
||||
// This test leaves out "Accessible by All" data element from the signed request
|
||||
// message (the CBOR from the reader) while still including this data element at
|
||||
// the API level. The call on the API level for said element will fail with
|
||||
// STATUS_NOT_IN_REQUEST_MESSAGE but this doesn't prevent the other elements
|
||||
// from being returned (if authorized, of course).
|
||||
//
|
||||
// This test verifies that.
|
||||
//
|
||||
TEST_P(ReaderAuthTests, limitedMessage) {
|
||||
provisionData();
|
||||
retrieveData(readerPrivateKey_, {cert_reader_SelfSigned_}, true /* expectSuccess */,
|
||||
true /* leaveOutAccessibleToAllFromRequestMessage */);
|
||||
EXPECT_FALSE(canGetAccessibleByA_);
|
||||
EXPECT_FALSE(canGetAccessibleByAorB_);
|
||||
EXPECT_FALSE(canGetAccessibleByB_);
|
||||
EXPECT_FALSE(canGetAccessibleByC_);
|
||||
EXPECT_FALSE(canGetAccessibleByAll_);
|
||||
EXPECT_FALSE(canGetAccessibleByNone_);
|
||||
}
|
||||
|
||||
TEST_P(ReaderAuthTests, ephemeralKeyNotInSessionTranscript) {
|
||||
provisionData();
|
||||
|
||||
sp<IIdentityCredential> c;
|
||||
ASSERT_TRUE(credentialStore_
|
||||
->getCredential(
|
||||
CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256,
|
||||
credentialData_, &c)
|
||||
.isOk());
|
||||
|
||||
optional<vector<uint8_t>> readerEKeyPair = support::createEcKeyPair();
|
||||
optional<vector<uint8_t>> readerEPublicKey =
|
||||
support::ecKeyPairGetPublicKey(readerEKeyPair.value());
|
||||
ASSERT_TRUE(c->setReaderEphemeralPublicKey(readerEPublicKey.value()).isOk());
|
||||
|
||||
vector<uint8_t> eKeyPair;
|
||||
ASSERT_TRUE(c->createEphemeralKeyPair(&eKeyPair).isOk());
|
||||
optional<vector<uint8_t>> ePublicKey = support::ecKeyPairGetPublicKey(eKeyPair);
|
||||
|
||||
// Calculate requestData field and sign it with the reader key.
|
||||
auto [getXYSuccess, ephX, ephY] = support::ecPublicKeyGetXandY(ePublicKey.value());
|
||||
ASSERT_TRUE(getXYSuccess);
|
||||
// Instead of include the X and Y coordinates (|ephX| and |ephY|), add NUL bytes instead.
|
||||
vector<uint8_t> nulls(32);
|
||||
cppbor::Map deviceEngagement = cppbor::Map().add("ephX", nulls).add("ephY", nulls);
|
||||
vector<uint8_t> deviceEngagementBytes = deviceEngagement.encode();
|
||||
vector<uint8_t> eReaderPubBytes = cppbor::Tstr("ignored").encode();
|
||||
cppbor::Array sessionTranscript = cppbor::Array()
|
||||
.add(cppbor::Semantic(24, deviceEngagementBytes))
|
||||
.add(cppbor::Semantic(24, eReaderPubBytes));
|
||||
vector<uint8_t> sessionTranscriptBytes = sessionTranscript.encode();
|
||||
|
||||
vector<uint8_t> itemsRequestBytes;
|
||||
itemsRequestBytes =
|
||||
cppbor::Map("nameSpaces",
|
||||
cppbor::Map().add("ns", cppbor::Map()
|
||||
.add("Accessible by A", false)
|
||||
.add("Accessible by A or B", false)
|
||||
.add("Accessible by B", false)
|
||||
.add("Accessible by C", false)
|
||||
.add("Accessible by None", false)))
|
||||
.encode();
|
||||
vector<uint8_t> encodedReaderAuthentication =
|
||||
cppbor::Array()
|
||||
.add("ReaderAuthentication")
|
||||
.add(sessionTranscript.clone())
|
||||
.add(cppbor::Semantic(24, itemsRequestBytes))
|
||||
.encode();
|
||||
vector<uint8_t> encodedReaderAuthenticationBytes =
|
||||
cppbor::Semantic(24, encodedReaderAuthentication).encode();
|
||||
|
||||
vector<vector<uint8_t>> readerCertChain = {cert_reader_SelfSigned_};
|
||||
optional<vector<uint8_t>> readerSignature =
|
||||
support::coseSignEcDsa(readerPrivateKey_, // private key for reader
|
||||
{}, // content
|
||||
encodedReaderAuthenticationBytes, // detached content
|
||||
support::certificateChainJoin(readerCertChain));
|
||||
ASSERT_TRUE(readerSignature);
|
||||
|
||||
// Generate the key that will be used to sign AuthenticatedData.
|
||||
vector<uint8_t> signingKeyBlob;
|
||||
Certificate signingKeyCertificate;
|
||||
ASSERT_TRUE(c->generateSigningKeyPair(&signingKeyBlob, &signingKeyCertificate).isOk());
|
||||
|
||||
RequestNamespace rns;
|
||||
rns.namespaceName = "ns";
|
||||
rns.items.push_back(buildRequestDataItem("Accessible by A", 1, {0}));
|
||||
rns.items.push_back(buildRequestDataItem("Accessible by A or B", 1, {0, 1}));
|
||||
rns.items.push_back(buildRequestDataItem("Accessible by B", 1, {1}));
|
||||
rns.items.push_back(buildRequestDataItem("Accessible by C", 1, {2}));
|
||||
rns.items.push_back(buildRequestDataItem("Accessible by All", 1, {3}));
|
||||
rns.items.push_back(buildRequestDataItem("Accessible by None", 1, {}));
|
||||
// OK to fail, not available in v1 HAL
|
||||
c->setRequestedNamespaces({rns}).isOk();
|
||||
|
||||
// It doesn't matter since no user auth is needed in this particular test,
|
||||
// but for good measure, clear out the tokens we pass to the HAL.
|
||||
HardwareAuthToken authToken;
|
||||
VerificationToken verificationToken;
|
||||
authToken.challenge = 0;
|
||||
authToken.userId = 0;
|
||||
authToken.authenticatorId = 0;
|
||||
authToken.authenticatorType = ::android::hardware::keymaster::HardwareAuthenticatorType::NONE;
|
||||
authToken.timestamp.milliSeconds = 0;
|
||||
authToken.mac.clear();
|
||||
verificationToken.challenge = 0;
|
||||
verificationToken.timestamp.milliSeconds = 0;
|
||||
verificationToken.securityLevel =
|
||||
::android::hardware::keymaster::SecurityLevel::TRUSTED_ENVIRONMENT;
|
||||
verificationToken.mac.clear();
|
||||
// OK to fail, not available in v1 HAL
|
||||
c->setVerificationToken(verificationToken);
|
||||
|
||||
// Finally check that STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND is returned.
|
||||
// This proves that the TA checked for X and Y coordinatets and didn't find
|
||||
// them.
|
||||
Status status = c->startRetrieval(
|
||||
{sacp0_, sacp1_, sacp2_, sacp3_}, authToken, itemsRequestBytes, signingKeyBlob,
|
||||
sessionTranscriptBytes, readerSignature.value(), {6 /* numDataElementsPerNamespace */});
|
||||
ASSERT_FALSE(status.isOk());
|
||||
ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
|
||||
ASSERT_EQ(IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND,
|
||||
status.serviceSpecificErrorCode());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
Identity, ReaderAuthTests,
|
||||
testing::ValuesIn(android::getAidlHalInstanceNames(IIdentityCredentialStore::descriptor)),
|
||||
android::PrintInstanceNameToString);
|
||||
|
||||
} // namespace android::hardware::identity
|
||||
473
identity/aidl/vts/UserAuthTests.cpp
Normal file
473
identity/aidl/vts/UserAuthTests.cpp
Normal file
@@ -0,0 +1,473 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "UserAuthTests"
|
||||
|
||||
#include <aidl/Gtest.h>
|
||||
#include <aidl/Vintf.h>
|
||||
#include <aidl/android/hardware/keymaster/HardwareAuthToken.h>
|
||||
#include <aidl/android/hardware/keymaster/VerificationToken.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android/hardware/identity/IIdentityCredentialStore.h>
|
||||
#include <android/hardware/identity/support/IdentityCredentialSupport.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <binder/ProcessState.h>
|
||||
#include <cppbor.h>
|
||||
#include <cppbor_parse.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <future>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
#include "VtsIdentityTestUtils.h"
|
||||
|
||||
namespace android::hardware::identity {
|
||||
|
||||
using std::endl;
|
||||
using std::make_pair;
|
||||
using std::map;
|
||||
using std::optional;
|
||||
using std::pair;
|
||||
using std::string;
|
||||
using std::tie;
|
||||
using std::vector;
|
||||
|
||||
using ::android::sp;
|
||||
using ::android::String16;
|
||||
using ::android::binder::Status;
|
||||
|
||||
using ::android::hardware::keymaster::HardwareAuthToken;
|
||||
using ::android::hardware::keymaster::VerificationToken;
|
||||
|
||||
class UserAuthTests : public testing::TestWithParam<string> {
|
||||
public:
|
||||
virtual void SetUp() override {
|
||||
credentialStore_ = android::waitForDeclaredService<IIdentityCredentialStore>(
|
||||
String16(GetParam().c_str()));
|
||||
ASSERT_NE(credentialStore_, nullptr);
|
||||
}
|
||||
|
||||
void provisionData();
|
||||
void setupRetrieveData();
|
||||
pair<HardwareAuthToken, VerificationToken> mintTokens(uint64_t challengeForAuthToken,
|
||||
int64_t ageOfAuthTokenMilliSeconds);
|
||||
void retrieveData(HardwareAuthToken authToken, VerificationToken verificationToken,
|
||||
bool expectSuccess, bool useSessionTranscript);
|
||||
|
||||
// Set by provisionData
|
||||
SecureAccessControlProfile sacp0_;
|
||||
SecureAccessControlProfile sacp1_;
|
||||
SecureAccessControlProfile sacp2_;
|
||||
|
||||
vector<uint8_t> encContentUserAuthPerSession_;
|
||||
vector<uint8_t> encContentUserAuthTimeout_;
|
||||
vector<uint8_t> encContentAccessibleByAll_;
|
||||
vector<uint8_t> encContentAccessibleByNone_;
|
||||
|
||||
vector<uint8_t> credentialData_;
|
||||
|
||||
// Set by setupRetrieveData().
|
||||
int64_t authChallenge_;
|
||||
cppbor::Map sessionTranscript_;
|
||||
sp<IIdentityCredential> credential_;
|
||||
|
||||
// Set by retrieveData()
|
||||
bool canGetUserAuthPerSession_;
|
||||
bool canGetUserAuthTimeout_;
|
||||
bool canGetAccessibleByAll_;
|
||||
bool canGetAccessibleByNone_;
|
||||
|
||||
sp<IIdentityCredentialStore> credentialStore_;
|
||||
};
|
||||
|
||||
void UserAuthTests::provisionData() {
|
||||
string docType = "org.iso.18013-5.2019.mdl";
|
||||
bool testCredential = true;
|
||||
sp<IWritableIdentityCredential> wc;
|
||||
ASSERT_TRUE(credentialStore_->createCredential(docType, testCredential, &wc).isOk());
|
||||
|
||||
vector<uint8_t> attestationApplicationId = {};
|
||||
vector<uint8_t> attestationChallenge = {1};
|
||||
vector<Certificate> certChain;
|
||||
ASSERT_TRUE(wc->getAttestationCertificate(attestationApplicationId, attestationChallenge,
|
||||
&certChain)
|
||||
.isOk());
|
||||
|
||||
size_t proofOfProvisioningSize = 381;
|
||||
// Not in v1 HAL, may fail
|
||||
wc->setExpectedProofOfProvisioningSize(proofOfProvisioningSize);
|
||||
|
||||
ASSERT_TRUE(wc->startPersonalization(3 /* numAccessControlProfiles */,
|
||||
{4} /* numDataElementsPerNamespace */)
|
||||
.isOk());
|
||||
|
||||
// Access control profile 0: user auth every session (timeout = 0)
|
||||
ASSERT_TRUE(wc->addAccessControlProfile(0, {}, true, 0, 65 /* secureUserId */, &sacp0_).isOk());
|
||||
|
||||
// Access control profile 1: user auth, 60 seconds timeout
|
||||
ASSERT_TRUE(
|
||||
wc->addAccessControlProfile(1, {}, true, 60000, 65 /* secureUserId */, &sacp1_).isOk());
|
||||
|
||||
// Access control profile 2: open access
|
||||
ASSERT_TRUE(wc->addAccessControlProfile(2, {}, false, 0, 0, &sacp2_).isOk());
|
||||
|
||||
// Data Element: "UserAuth Per Session"
|
||||
ASSERT_TRUE(wc->beginAddEntry({0}, "ns", "UserAuth Per Session", 1).isOk());
|
||||
ASSERT_TRUE(wc->addEntryValue({9}, &encContentUserAuthPerSession_).isOk());
|
||||
|
||||
// Data Element: "UserAuth Timeout"
|
||||
ASSERT_TRUE(wc->beginAddEntry({1}, "ns", "UserAuth Timeout", 1).isOk());
|
||||
ASSERT_TRUE(wc->addEntryValue({9}, &encContentUserAuthTimeout_).isOk());
|
||||
|
||||
// Data Element: "Accessible by All"
|
||||
ASSERT_TRUE(wc->beginAddEntry({2}, "ns", "Accessible by All", 1).isOk());
|
||||
ASSERT_TRUE(wc->addEntryValue({9}, &encContentAccessibleByAll_).isOk());
|
||||
|
||||
// Data Element: "Accessible by None"
|
||||
ASSERT_TRUE(wc->beginAddEntry({}, "ns", "Accessible by None", 1).isOk());
|
||||
ASSERT_TRUE(wc->addEntryValue({9}, &encContentAccessibleByNone_).isOk());
|
||||
|
||||
vector<uint8_t> proofOfProvisioningSignature;
|
||||
Status status = wc->finishAddingEntries(&credentialData_, &proofOfProvisioningSignature);
|
||||
EXPECT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage();
|
||||
}
|
||||
|
||||
// From ReaderAuthTest.cpp - TODO: consolidate with VtsIdentityTestUtils.h
|
||||
pair<vector<uint8_t>, vector<uint8_t>> generateReaderKey();
|
||||
vector<uint8_t> generateReaderCert(const vector<uint8_t>& publicKey,
|
||||
const vector<uint8_t>& signingKey);
|
||||
RequestDataItem buildRequestDataItem(const string& name, size_t size,
|
||||
vector<int32_t> accessControlProfileIds);
|
||||
|
||||
cppbor::Map calcSessionTranscript(const vector<uint8_t>& ePublicKey) {
|
||||
auto [getXYSuccess, ephX, ephY] = support::ecPublicKeyGetXandY(ePublicKey);
|
||||
cppbor::Map deviceEngagement = cppbor::Map().add("ephX", ephX).add("ephY", ephY);
|
||||
vector<uint8_t> deviceEngagementBytes = deviceEngagement.encode();
|
||||
vector<uint8_t> eReaderPubBytes = cppbor::Tstr("ignored").encode();
|
||||
// Let SessionTranscript be a map here (it's an array in EndToEndTest) just
|
||||
// to check that the implementation can deal with either.
|
||||
cppbor::Map sessionTranscript;
|
||||
sessionTranscript.add(42, cppbor::Semantic(24, deviceEngagementBytes));
|
||||
sessionTranscript.add(43, cppbor::Semantic(24, eReaderPubBytes));
|
||||
return sessionTranscript;
|
||||
}
|
||||
|
||||
void UserAuthTests::setupRetrieveData() {
|
||||
ASSERT_TRUE(credentialStore_
|
||||
->getCredential(
|
||||
CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256,
|
||||
credentialData_, &credential_)
|
||||
.isOk());
|
||||
|
||||
optional<vector<uint8_t>> readerEKeyPair = support::createEcKeyPair();
|
||||
optional<vector<uint8_t>> readerEPublicKey =
|
||||
support::ecKeyPairGetPublicKey(readerEKeyPair.value());
|
||||
ASSERT_TRUE(credential_->setReaderEphemeralPublicKey(readerEPublicKey.value()).isOk());
|
||||
|
||||
vector<uint8_t> eKeyPair;
|
||||
ASSERT_TRUE(credential_->createEphemeralKeyPair(&eKeyPair).isOk());
|
||||
optional<vector<uint8_t>> ePublicKey = support::ecKeyPairGetPublicKey(eKeyPair);
|
||||
sessionTranscript_ = calcSessionTranscript(ePublicKey.value());
|
||||
|
||||
Status status = credential_->createAuthChallenge(&authChallenge_);
|
||||
EXPECT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage();
|
||||
}
|
||||
|
||||
void UserAuthTests::retrieveData(HardwareAuthToken authToken, VerificationToken verificationToken,
|
||||
bool expectSuccess, bool useSessionTranscript) {
|
||||
canGetUserAuthPerSession_ = false;
|
||||
canGetUserAuthTimeout_ = false;
|
||||
canGetAccessibleByAll_ = false;
|
||||
canGetAccessibleByNone_ = false;
|
||||
|
||||
vector<uint8_t> itemsRequestBytes;
|
||||
vector<uint8_t> sessionTranscriptBytes;
|
||||
if (useSessionTranscript) {
|
||||
sessionTranscriptBytes = sessionTranscript_.encode();
|
||||
|
||||
itemsRequestBytes =
|
||||
cppbor::Map("nameSpaces",
|
||||
cppbor::Map().add("ns", cppbor::Map()
|
||||
.add("UserAuth Per Session", false)
|
||||
.add("UserAuth Timeout", false)
|
||||
.add("Accessible by All", false)
|
||||
.add("Accessible by None", false)))
|
||||
.encode();
|
||||
vector<uint8_t> dataToSign = cppbor::Array()
|
||||
.add("ReaderAuthentication")
|
||||
.add(sessionTranscript_.clone())
|
||||
.add(cppbor::Semantic(24, itemsRequestBytes))
|
||||
.encode();
|
||||
}
|
||||
|
||||
// Generate the key that will be used to sign AuthenticatedData.
|
||||
vector<uint8_t> signingKeyBlob;
|
||||
Certificate signingKeyCertificate;
|
||||
ASSERT_TRUE(
|
||||
credential_->generateSigningKeyPair(&signingKeyBlob, &signingKeyCertificate).isOk());
|
||||
|
||||
RequestNamespace rns;
|
||||
rns.namespaceName = "ns";
|
||||
rns.items.push_back(buildRequestDataItem("UserAuth Per Session", 1, {0}));
|
||||
rns.items.push_back(buildRequestDataItem("UserAuth Timeout", 1, {1}));
|
||||
rns.items.push_back(buildRequestDataItem("Accessible by All", 1, {2}));
|
||||
rns.items.push_back(buildRequestDataItem("Accessible by None", 1, {}));
|
||||
// OK to fail, not available in v1 HAL
|
||||
credential_->setRequestedNamespaces({rns}).isOk();
|
||||
|
||||
// OK to fail, not available in v1 HAL
|
||||
credential_->setVerificationToken(verificationToken);
|
||||
|
||||
Status status = credential_->startRetrieval({sacp0_, sacp1_, sacp2_}, authToken,
|
||||
itemsRequestBytes, signingKeyBlob,
|
||||
sessionTranscriptBytes, {} /* readerSignature */,
|
||||
{4 /* numDataElementsPerNamespace */});
|
||||
if (expectSuccess) {
|
||||
ASSERT_TRUE(status.isOk());
|
||||
} else {
|
||||
ASSERT_FALSE(status.isOk());
|
||||
return;
|
||||
}
|
||||
|
||||
vector<uint8_t> decrypted;
|
||||
|
||||
status = credential_->startRetrieveEntryValue("ns", "UserAuth Per Session", 1, {0});
|
||||
if (status.isOk()) {
|
||||
canGetUserAuthPerSession_ = true;
|
||||
ASSERT_TRUE(
|
||||
credential_->retrieveEntryValue(encContentUserAuthPerSession_, &decrypted).isOk());
|
||||
}
|
||||
|
||||
status = credential_->startRetrieveEntryValue("ns", "UserAuth Timeout", 1, {1});
|
||||
if (status.isOk()) {
|
||||
canGetUserAuthTimeout_ = true;
|
||||
ASSERT_TRUE(credential_->retrieveEntryValue(encContentUserAuthTimeout_, &decrypted).isOk());
|
||||
}
|
||||
|
||||
status = credential_->startRetrieveEntryValue("ns", "Accessible by All", 1, {2});
|
||||
if (status.isOk()) {
|
||||
canGetAccessibleByAll_ = true;
|
||||
ASSERT_TRUE(credential_->retrieveEntryValue(encContentAccessibleByAll_, &decrypted).isOk());
|
||||
}
|
||||
|
||||
status = credential_->startRetrieveEntryValue("ns", "Accessible by None", 1, {});
|
||||
if (status.isOk()) {
|
||||
canGetAccessibleByNone_ = true;
|
||||
ASSERT_TRUE(
|
||||
credential_->retrieveEntryValue(encContentAccessibleByNone_, &decrypted).isOk());
|
||||
}
|
||||
|
||||
vector<uint8_t> mac;
|
||||
vector<uint8_t> deviceNameSpaces;
|
||||
ASSERT_TRUE(credential_->finishRetrieval(&mac, &deviceNameSpaces).isOk());
|
||||
}
|
||||
|
||||
pair<HardwareAuthToken, VerificationToken> UserAuthTests::mintTokens(
|
||||
uint64_t challengeForAuthToken, int64_t ageOfAuthTokenMilliSeconds) {
|
||||
HardwareAuthToken authToken;
|
||||
VerificationToken verificationToken;
|
||||
|
||||
uint64_t epochMilliseconds = 1000ULL * 1000ULL * 1000ULL * 1000ULL;
|
||||
|
||||
authToken.challenge = challengeForAuthToken;
|
||||
authToken.userId = 65;
|
||||
authToken.authenticatorId = 0;
|
||||
authToken.authenticatorType = ::android::hardware::keymaster::HardwareAuthenticatorType::NONE;
|
||||
authToken.timestamp.milliSeconds = epochMilliseconds - ageOfAuthTokenMilliSeconds;
|
||||
authToken.mac.clear();
|
||||
verificationToken.challenge = authChallenge_;
|
||||
verificationToken.timestamp.milliSeconds = epochMilliseconds;
|
||||
verificationToken.securityLevel =
|
||||
::android::hardware::keymaster::SecurityLevel::TRUSTED_ENVIRONMENT;
|
||||
verificationToken.mac.clear();
|
||||
return make_pair(authToken, verificationToken);
|
||||
}
|
||||
|
||||
TEST_P(UserAuthTests, GoodChallenge) {
|
||||
provisionData();
|
||||
setupRetrieveData();
|
||||
auto [authToken, verificationToken] = mintTokens(authChallenge_, // challengeForAuthToken
|
||||
0); // ageOfAuthTokenMilliSeconds
|
||||
retrieveData(authToken, verificationToken, true /* expectSuccess */,
|
||||
true /* useSessionTranscript */);
|
||||
EXPECT_TRUE(canGetUserAuthPerSession_);
|
||||
EXPECT_TRUE(canGetUserAuthTimeout_);
|
||||
EXPECT_TRUE(canGetAccessibleByAll_);
|
||||
EXPECT_FALSE(canGetAccessibleByNone_);
|
||||
}
|
||||
|
||||
TEST_P(UserAuthTests, OtherChallenge) {
|
||||
provisionData();
|
||||
setupRetrieveData();
|
||||
uint64_t otherChallenge = authChallenge_ ^ 0x12345678;
|
||||
auto [authToken, verificationToken] = mintTokens(otherChallenge, // challengeForAuthToken
|
||||
0); // ageOfAuthTokenMilliSeconds
|
||||
retrieveData(authToken, verificationToken, true /* expectSuccess */,
|
||||
true /* useSessionTranscript */);
|
||||
EXPECT_FALSE(canGetUserAuthPerSession_);
|
||||
EXPECT_TRUE(canGetUserAuthTimeout_);
|
||||
EXPECT_TRUE(canGetAccessibleByAll_);
|
||||
EXPECT_FALSE(canGetAccessibleByNone_);
|
||||
}
|
||||
|
||||
TEST_P(UserAuthTests, NoChallenge) {
|
||||
provisionData();
|
||||
setupRetrieveData();
|
||||
auto [authToken, verificationToken] = mintTokens(0, // challengeForAuthToken
|
||||
0); // ageOfAuthTokenMilliSeconds
|
||||
retrieveData(authToken, verificationToken, true /* expectSuccess */,
|
||||
true /* useSessionTranscript */);
|
||||
EXPECT_FALSE(canGetUserAuthPerSession_);
|
||||
EXPECT_TRUE(canGetUserAuthTimeout_);
|
||||
EXPECT_TRUE(canGetAccessibleByAll_);
|
||||
EXPECT_FALSE(canGetAccessibleByNone_);
|
||||
}
|
||||
|
||||
TEST_P(UserAuthTests, AuthTokenAgeZero) {
|
||||
provisionData();
|
||||
setupRetrieveData();
|
||||
auto [authToken, verificationToken] = mintTokens(0, // challengeForAuthToken
|
||||
0); // ageOfAuthTokenMilliSeconds
|
||||
retrieveData(authToken, verificationToken, true /* expectSuccess */,
|
||||
true /* useSessionTranscript */);
|
||||
EXPECT_FALSE(canGetUserAuthPerSession_);
|
||||
EXPECT_TRUE(canGetUserAuthTimeout_);
|
||||
EXPECT_TRUE(canGetAccessibleByAll_);
|
||||
EXPECT_FALSE(canGetAccessibleByNone_);
|
||||
}
|
||||
|
||||
TEST_P(UserAuthTests, AuthTokenFromTheFuture) {
|
||||
provisionData();
|
||||
setupRetrieveData();
|
||||
auto [authToken, verificationToken] = mintTokens(0, // challengeForAuthToken
|
||||
-1 * 1000); // ageOfAuthTokenMilliSeconds
|
||||
retrieveData(authToken, verificationToken, true /* expectSuccess */,
|
||||
true /* useSessionTranscript */);
|
||||
EXPECT_FALSE(canGetUserAuthPerSession_);
|
||||
EXPECT_FALSE(canGetUserAuthTimeout_);
|
||||
EXPECT_TRUE(canGetAccessibleByAll_);
|
||||
EXPECT_FALSE(canGetAccessibleByNone_);
|
||||
}
|
||||
|
||||
TEST_P(UserAuthTests, AuthTokenInsideTimeout) {
|
||||
provisionData();
|
||||
setupRetrieveData();
|
||||
auto [authToken, verificationToken] = mintTokens(0, // challengeForAuthToken
|
||||
30 * 1000); // ageOfAuthTokenMilliSeconds
|
||||
retrieveData(authToken, verificationToken, true /* expectSuccess */,
|
||||
true /* useSessionTranscript */);
|
||||
EXPECT_FALSE(canGetUserAuthPerSession_);
|
||||
EXPECT_TRUE(canGetUserAuthTimeout_);
|
||||
EXPECT_TRUE(canGetAccessibleByAll_);
|
||||
EXPECT_FALSE(canGetAccessibleByNone_);
|
||||
}
|
||||
|
||||
TEST_P(UserAuthTests, AuthTokenOutsideTimeout) {
|
||||
provisionData();
|
||||
setupRetrieveData();
|
||||
auto [authToken, verificationToken] = mintTokens(0, // challengeForAuthToken
|
||||
61 * 1000); // ageOfAuthTokenMilliSeconds
|
||||
retrieveData(authToken, verificationToken, true /* expectSuccess */,
|
||||
true /* useSessionTranscript */);
|
||||
EXPECT_FALSE(canGetUserAuthPerSession_);
|
||||
EXPECT_FALSE(canGetUserAuthTimeout_);
|
||||
EXPECT_TRUE(canGetAccessibleByAll_);
|
||||
EXPECT_FALSE(canGetAccessibleByNone_);
|
||||
}
|
||||
|
||||
// The API works even when there's no SessionTranscript / itemsRequest.
|
||||
// Verify that.
|
||||
TEST_P(UserAuthTests, NoSessionTranscript) {
|
||||
provisionData();
|
||||
setupRetrieveData();
|
||||
auto [authToken, verificationToken] = mintTokens(0, // challengeForAuthToken
|
||||
1 * 1000); // ageOfAuthTokenMilliSeconds
|
||||
retrieveData(authToken, verificationToken, true /* expectSuccess */,
|
||||
false /* useSessionTranscript */);
|
||||
EXPECT_FALSE(canGetUserAuthPerSession_);
|
||||
EXPECT_TRUE(canGetUserAuthTimeout_);
|
||||
EXPECT_TRUE(canGetAccessibleByAll_);
|
||||
EXPECT_FALSE(canGetAccessibleByNone_);
|
||||
}
|
||||
|
||||
// This test verifies that it's possible to do multiple requests as long
|
||||
// as the sessionTranscript doesn't change.
|
||||
//
|
||||
TEST_P(UserAuthTests, MultipleRequestsSameSessionTranscript) {
|
||||
provisionData();
|
||||
setupRetrieveData();
|
||||
|
||||
// First we try with a stale authToken
|
||||
//
|
||||
auto [authToken, verificationToken] = mintTokens(0, // challengeForAuthToken
|
||||
61 * 1000); // ageOfAuthTokenMilliSeconds
|
||||
retrieveData(authToken, verificationToken, true /* expectSuccess */,
|
||||
true /* useSessionTranscript */);
|
||||
EXPECT_FALSE(canGetUserAuthPerSession_);
|
||||
EXPECT_FALSE(canGetUserAuthTimeout_);
|
||||
EXPECT_TRUE(canGetAccessibleByAll_);
|
||||
EXPECT_FALSE(canGetAccessibleByNone_);
|
||||
|
||||
// Then we get a new authToken and try again.
|
||||
tie(authToken, verificationToken) = mintTokens(0, // challengeForAuthToken
|
||||
5 * 1000); // ageOfAuthTokenMilliSeconds
|
||||
retrieveData(authToken, verificationToken, true /* expectSuccess */,
|
||||
true /* useSessionTranscript */);
|
||||
EXPECT_FALSE(canGetUserAuthPerSession_);
|
||||
EXPECT_TRUE(canGetUserAuthTimeout_);
|
||||
EXPECT_TRUE(canGetAccessibleByAll_);
|
||||
EXPECT_FALSE(canGetAccessibleByNone_);
|
||||
}
|
||||
|
||||
// Like MultipleRequestsSameSessionTranscript but we change the sessionTranscript
|
||||
// between the two calls. This test verifies that change is detected and the
|
||||
// second request fails.
|
||||
//
|
||||
TEST_P(UserAuthTests, MultipleRequestsSessionTranscriptChanges) {
|
||||
provisionData();
|
||||
setupRetrieveData();
|
||||
|
||||
// First we try with a stale authToken
|
||||
//
|
||||
auto [authToken, verificationToken] = mintTokens(0, // challengeForAuthToken
|
||||
61 * 1000); // ageOfAuthTokenMilliSeconds
|
||||
retrieveData(authToken, verificationToken, true /* expectSuccess */,
|
||||
true /* useSessionTranscript */);
|
||||
EXPECT_FALSE(canGetUserAuthPerSession_);
|
||||
EXPECT_FALSE(canGetUserAuthTimeout_);
|
||||
EXPECT_TRUE(canGetAccessibleByAll_);
|
||||
EXPECT_FALSE(canGetAccessibleByNone_);
|
||||
|
||||
// Then we get a new authToken and try again.
|
||||
tie(authToken, verificationToken) = mintTokens(0, // challengeForAuthToken
|
||||
5 * 1000); // ageOfAuthTokenMilliSeconds
|
||||
|
||||
// Change sessionTranscript...
|
||||
optional<vector<uint8_t>> eKeyPairNew = support::createEcKeyPair();
|
||||
optional<vector<uint8_t>> ePublicKeyNew = support::ecKeyPairGetPublicKey(eKeyPairNew.value());
|
||||
sessionTranscript_ = calcSessionTranscript(ePublicKeyNew.value());
|
||||
|
||||
// ... and expect failure.
|
||||
retrieveData(authToken, verificationToken, false /* expectSuccess */,
|
||||
true /* useSessionTranscript */);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
Identity, UserAuthTests,
|
||||
testing::ValuesIn(android::getAidlHalInstanceNames(IIdentityCredentialStore::descriptor)),
|
||||
android::PrintInstanceNameToString);
|
||||
|
||||
} // namespace android::hardware::identity
|
||||
@@ -61,51 +61,6 @@ class VtsAttestationTests : public testing::TestWithParam<std::string> {
|
||||
sp<IIdentityCredentialStore> credentialStore_;
|
||||
};
|
||||
|
||||
TEST_P(VtsAttestationTests, verifyAttestationWithEmptyChallengeEmptyId) {
|
||||
Status result;
|
||||
|
||||
HardwareInformation hwInfo;
|
||||
ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
|
||||
|
||||
sp<IWritableIdentityCredential> writableCredential;
|
||||
ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_));
|
||||
|
||||
vector<uint8_t> attestationChallenge;
|
||||
vector<Certificate> attestationCertificate;
|
||||
vector<uint8_t> attestationApplicationId = {};
|
||||
result = writableCredential->getAttestationCertificate(
|
||||
attestationApplicationId, attestationChallenge, &attestationCertificate);
|
||||
|
||||
ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
|
||||
<< endl;
|
||||
|
||||
EXPECT_TRUE(validateAttestationCertificate(attestationCertificate, attestationChallenge,
|
||||
attestationApplicationId, hwInfo));
|
||||
}
|
||||
|
||||
TEST_P(VtsAttestationTests, verifyAttestationWithEmptyChallengeNonemptyId) {
|
||||
Status result;
|
||||
|
||||
HardwareInformation hwInfo;
|
||||
ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
|
||||
|
||||
sp<IWritableIdentityCredential> writableCredential;
|
||||
ASSERT_TRUE(setupWritableCredential(writableCredential, credentialStore_));
|
||||
|
||||
vector<uint8_t> attestationChallenge;
|
||||
vector<Certificate> attestationCertificate;
|
||||
string applicationId = "Attestation Verification";
|
||||
vector<uint8_t> attestationApplicationId = {applicationId.begin(), applicationId.end()};
|
||||
|
||||
result = writableCredential->getAttestationCertificate(
|
||||
attestationApplicationId, attestationChallenge, &attestationCertificate);
|
||||
|
||||
ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
|
||||
<< endl;
|
||||
EXPECT_TRUE(validateAttestationCertificate(attestationCertificate, attestationChallenge,
|
||||
attestationApplicationId, hwInfo));
|
||||
}
|
||||
|
||||
TEST_P(VtsAttestationTests, verifyAttestationWithNonemptyChallengeEmptyId) {
|
||||
Status result;
|
||||
|
||||
|
||||
@@ -27,15 +27,18 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <future>
|
||||
#include <map>
|
||||
#include <tuple>
|
||||
|
||||
#include "VtsIdentityTestUtils.h"
|
||||
|
||||
namespace android::hardware::identity {
|
||||
|
||||
using std::endl;
|
||||
using std::make_tuple;
|
||||
using std::map;
|
||||
using std::optional;
|
||||
using std::string;
|
||||
using std::tuple;
|
||||
using std::vector;
|
||||
|
||||
using ::android::sp;
|
||||
@@ -66,6 +69,61 @@ TEST_P(IdentityAidl, hardwareInformation) {
|
||||
ASSERT_GE(info.dataChunkSize, 256);
|
||||
}
|
||||
|
||||
tuple<bool, string, vector<uint8_t>, vector<uint8_t>> extractFromTestCredentialData(
|
||||
const vector<uint8_t>& credentialData) {
|
||||
string docType;
|
||||
vector<uint8_t> storageKey;
|
||||
vector<uint8_t> credentialPrivKey;
|
||||
|
||||
auto [item, _, message] = cppbor::parse(credentialData);
|
||||
if (item == nullptr) {
|
||||
return make_tuple(false, docType, storageKey, credentialPrivKey);
|
||||
}
|
||||
|
||||
const cppbor::Array* arrayItem = item->asArray();
|
||||
if (arrayItem == nullptr || arrayItem->size() != 3) {
|
||||
return make_tuple(false, docType, storageKey, credentialPrivKey);
|
||||
}
|
||||
|
||||
const cppbor::Tstr* docTypeItem = (*arrayItem)[0]->asTstr();
|
||||
const cppbor::Bool* testCredentialItem =
|
||||
((*arrayItem)[1]->asSimple() != nullptr ? ((*arrayItem)[1]->asSimple()->asBool())
|
||||
: nullptr);
|
||||
const cppbor::Bstr* encryptedCredentialKeysItem = (*arrayItem)[2]->asBstr();
|
||||
if (docTypeItem == nullptr || testCredentialItem == nullptr ||
|
||||
encryptedCredentialKeysItem == nullptr) {
|
||||
return make_tuple(false, docType, storageKey, credentialPrivKey);
|
||||
}
|
||||
|
||||
docType = docTypeItem->value();
|
||||
|
||||
vector<uint8_t> hardwareBoundKey = support::getTestHardwareBoundKey();
|
||||
const vector<uint8_t>& encryptedCredentialKeys = encryptedCredentialKeysItem->value();
|
||||
const vector<uint8_t> docTypeVec(docType.begin(), docType.end());
|
||||
optional<vector<uint8_t>> decryptedCredentialKeys =
|
||||
support::decryptAes128Gcm(hardwareBoundKey, encryptedCredentialKeys, docTypeVec);
|
||||
if (!decryptedCredentialKeys) {
|
||||
return make_tuple(false, docType, storageKey, credentialPrivKey);
|
||||
}
|
||||
|
||||
auto [dckItem, dckPos, dckMessage] = cppbor::parse(decryptedCredentialKeys.value());
|
||||
if (dckItem == nullptr) {
|
||||
return make_tuple(false, docType, storageKey, credentialPrivKey);
|
||||
}
|
||||
const cppbor::Array* dckArrayItem = dckItem->asArray();
|
||||
if (dckArrayItem == nullptr || dckArrayItem->size() != 2) {
|
||||
return make_tuple(false, docType, storageKey, credentialPrivKey);
|
||||
}
|
||||
const cppbor::Bstr* storageKeyItem = (*dckArrayItem)[0]->asBstr();
|
||||
const cppbor::Bstr* credentialPrivKeyItem = (*dckArrayItem)[1]->asBstr();
|
||||
if (storageKeyItem == nullptr || credentialPrivKeyItem == nullptr) {
|
||||
return make_tuple(false, docType, storageKey, credentialPrivKey);
|
||||
}
|
||||
storageKey = storageKeyItem->value();
|
||||
credentialPrivKey = credentialPrivKeyItem->value();
|
||||
return make_tuple(true, docType, storageKey, credentialPrivKey);
|
||||
}
|
||||
|
||||
TEST_P(IdentityAidl, createAndRetrieveCredential) {
|
||||
// First, generate a key-pair for the reader since its public key will be
|
||||
// part of the request data.
|
||||
@@ -155,6 +213,7 @@ TEST_P(IdentityAidl, createAndRetrieveCredential) {
|
||||
writableCredential->finishAddingEntries(&credentialData, &proofOfProvisioningSignature)
|
||||
.isOk());
|
||||
|
||||
// Validate the proofOfProvisioning which was returned
|
||||
optional<vector<uint8_t>> proofOfProvisioning =
|
||||
support::coseSignGetPayload(proofOfProvisioningSignature);
|
||||
ASSERT_TRUE(proofOfProvisioning);
|
||||
@@ -215,6 +274,22 @@ TEST_P(IdentityAidl, createAndRetrieveCredential) {
|
||||
credentialPubKey.value()));
|
||||
writableCredential = nullptr;
|
||||
|
||||
// Extract doctype, storage key, and credentialPrivKey from credentialData... this works
|
||||
// only because we asked for a test-credential meaning that the HBK is all zeroes.
|
||||
auto [exSuccess, exDocType, exStorageKey, exCredentialPrivKey] =
|
||||
extractFromTestCredentialData(credentialData);
|
||||
ASSERT_TRUE(exSuccess);
|
||||
ASSERT_EQ(exDocType, "org.iso.18013-5.2019.mdl");
|
||||
// ... check that the public key derived from the private key matches what was
|
||||
// in the certificate.
|
||||
optional<vector<uint8_t>> exCredentialKeyPair =
|
||||
support::ecPrivateKeyToKeyPair(exCredentialPrivKey);
|
||||
ASSERT_TRUE(exCredentialKeyPair);
|
||||
optional<vector<uint8_t>> exCredentialPubKey =
|
||||
support::ecKeyPairGetPublicKey(exCredentialKeyPair.value());
|
||||
ASSERT_TRUE(exCredentialPubKey);
|
||||
ASSERT_EQ(exCredentialPubKey.value(), credentialPubKey.value());
|
||||
|
||||
// Now that the credential has been provisioned, read it back and check the
|
||||
// correct data is returned.
|
||||
sp<IIdentityCredential> credential;
|
||||
@@ -244,7 +319,7 @@ TEST_P(IdentityAidl, createAndRetrieveCredential) {
|
||||
cppbor::Array sessionTranscript = cppbor::Array()
|
||||
.add(cppbor::Semantic(24, deviceEngagementBytes))
|
||||
.add(cppbor::Semantic(24, eReaderPubBytes));
|
||||
vector<uint8_t> sessionTranscriptBytes = sessionTranscript.encode();
|
||||
vector<uint8_t> sessionTranscriptEncoded = sessionTranscript.encode();
|
||||
|
||||
vector<uint8_t> itemsRequestBytes =
|
||||
cppbor::Map("nameSpaces",
|
||||
@@ -272,14 +347,17 @@ TEST_P(IdentityAidl, createAndRetrieveCredential) {
|
||||
" },\n"
|
||||
"}",
|
||||
cborPretty);
|
||||
vector<uint8_t> dataToSign = cppbor::Array()
|
||||
.add("ReaderAuthentication")
|
||||
.add(sessionTranscript.clone())
|
||||
.add(cppbor::Semantic(24, itemsRequestBytes))
|
||||
.encode();
|
||||
vector<uint8_t> encodedReaderAuthentication =
|
||||
cppbor::Array()
|
||||
.add("ReaderAuthentication")
|
||||
.add(sessionTranscript.clone())
|
||||
.add(cppbor::Semantic(24, itemsRequestBytes))
|
||||
.encode();
|
||||
vector<uint8_t> encodedReaderAuthenticationBytes =
|
||||
cppbor::Semantic(24, encodedReaderAuthentication).encode();
|
||||
optional<vector<uint8_t>> readerSignature =
|
||||
support::coseSignEcDsa(readerKey, {}, // content
|
||||
dataToSign, // detached content
|
||||
support::coseSignEcDsa(readerKey, {}, // content
|
||||
encodedReaderAuthenticationBytes, // detached content
|
||||
readerCertificate.value());
|
||||
ASSERT_TRUE(readerSignature);
|
||||
|
||||
@@ -287,15 +365,33 @@ TEST_P(IdentityAidl, createAndRetrieveCredential) {
|
||||
vector<uint8_t> signingKeyBlob;
|
||||
Certificate signingKeyCertificate;
|
||||
ASSERT_TRUE(credential->generateSigningKeyPair(&signingKeyBlob, &signingKeyCertificate).isOk());
|
||||
optional<vector<uint8_t>> signingPubKey =
|
||||
support::certificateChainGetTopMostKey(signingKeyCertificate.encodedCertificate);
|
||||
EXPECT_TRUE(signingPubKey);
|
||||
|
||||
// Since we're using a test-credential we know storageKey meaning we can get the
|
||||
// private key. Do this, derive the public key from it, and check this matches what
|
||||
// is in the certificate...
|
||||
const vector<uint8_t> exDocTypeVec(exDocType.begin(), exDocType.end());
|
||||
optional<vector<uint8_t>> exSigningPrivKey =
|
||||
support::decryptAes128Gcm(exStorageKey, signingKeyBlob, exDocTypeVec);
|
||||
ASSERT_TRUE(exSigningPrivKey);
|
||||
optional<vector<uint8_t>> exSigningKeyPair =
|
||||
support::ecPrivateKeyToKeyPair(exSigningPrivKey.value());
|
||||
ASSERT_TRUE(exSigningKeyPair);
|
||||
optional<vector<uint8_t>> exSigningPubKey =
|
||||
support::ecKeyPairGetPublicKey(exSigningKeyPair.value());
|
||||
ASSERT_TRUE(exSigningPubKey);
|
||||
ASSERT_EQ(exSigningPubKey.value(), signingPubKey.value());
|
||||
|
||||
vector<RequestNamespace> requestedNamespaces = test_utils::buildRequestNamespaces(testEntries);
|
||||
// OK to fail, not available in v1 HAL
|
||||
credential->setRequestedNamespaces(requestedNamespaces).isOk();
|
||||
credential->setRequestedNamespaces(requestedNamespaces);
|
||||
// OK to fail, not available in v1 HAL
|
||||
credential->setVerificationToken(verificationToken);
|
||||
ASSERT_TRUE(credential
|
||||
->startRetrieval(secureProfiles.value(), authToken, itemsRequestBytes,
|
||||
signingKeyBlob, sessionTranscriptBytes,
|
||||
signingKeyBlob, sessionTranscriptEncoded,
|
||||
readerSignature.value(), testEntriesEntryCounts)
|
||||
.isOk());
|
||||
|
||||
@@ -316,6 +412,9 @@ TEST_P(IdentityAidl, createAndRetrieveCredential) {
|
||||
content.insert(content.end(), chunk.begin(), chunk.end());
|
||||
}
|
||||
EXPECT_EQ(content, entry.valueCbor);
|
||||
|
||||
// TODO: also use |exStorageKey| to decrypt data and check it's the same as whatt
|
||||
// the HAL returns...
|
||||
}
|
||||
|
||||
vector<uint8_t> mac;
|
||||
@@ -336,7 +435,7 @@ TEST_P(IdentityAidl, createAndRetrieveCredential) {
|
||||
" },\n"
|
||||
"}",
|
||||
cborPretty);
|
||||
// The data that is MACed is ["DeviceAuthentication", sessionTranscriptBytes, docType,
|
||||
// The data that is MACed is ["DeviceAuthentication", sessionTranscript, docType,
|
||||
// deviceNameSpacesBytes] so build up that structure
|
||||
cppbor::Array deviceAuthentication;
|
||||
deviceAuthentication.add("DeviceAuthentication");
|
||||
@@ -345,24 +444,80 @@ TEST_P(IdentityAidl, createAndRetrieveCredential) {
|
||||
string docType = "org.iso.18013-5.2019.mdl";
|
||||
deviceAuthentication.add(docType);
|
||||
deviceAuthentication.add(cppbor::Semantic(24, deviceNameSpacesBytes));
|
||||
vector<uint8_t> encodedDeviceAuthentication = deviceAuthentication.encode();
|
||||
optional<vector<uint8_t>> signingPublicKey =
|
||||
support::certificateChainGetTopMostKey(signingKeyCertificate.encodedCertificate);
|
||||
EXPECT_TRUE(signingPublicKey);
|
||||
|
||||
vector<uint8_t> deviceAuthenticationBytes =
|
||||
cppbor::Semantic(24, deviceAuthentication.encode()).encode();
|
||||
// Derive the key used for MACing.
|
||||
optional<vector<uint8_t>> readerEphemeralPrivateKey =
|
||||
support::ecKeyPairGetPrivateKey(readerEphemeralKeyPair.value());
|
||||
optional<vector<uint8_t>> sharedSecret =
|
||||
support::ecdh(signingPublicKey.value(), readerEphemeralPrivateKey.value());
|
||||
support::ecdh(signingPubKey.value(), readerEphemeralPrivateKey.value());
|
||||
ASSERT_TRUE(sharedSecret);
|
||||
// Mix-in SessionTranscriptBytes
|
||||
vector<uint8_t> sessionTranscriptBytes =
|
||||
cppbor::Semantic(24, sessionTranscript.encode()).encode();
|
||||
vector<uint8_t> sharedSecretWithSessionTranscriptBytes = sharedSecret.value();
|
||||
std::copy(sessionTranscriptBytes.begin(), sessionTranscriptBytes.end(),
|
||||
std::back_inserter(sharedSecretWithSessionTranscriptBytes));
|
||||
vector<uint8_t> salt = {0x00};
|
||||
vector<uint8_t> info = {};
|
||||
optional<vector<uint8_t>> derivedKey = support::hkdf(sharedSecret.value(), salt, info, 32);
|
||||
optional<vector<uint8_t>> derivedKey =
|
||||
support::hkdf(sharedSecretWithSessionTranscriptBytes, salt, info, 32);
|
||||
ASSERT_TRUE(derivedKey);
|
||||
optional<vector<uint8_t>> calculatedMac =
|
||||
support::coseMac0(derivedKey.value(), {}, // payload
|
||||
encodedDeviceAuthentication); // detached content
|
||||
support::coseMac0(derivedKey.value(), {}, // payload
|
||||
deviceAuthenticationBytes); // detached content
|
||||
ASSERT_TRUE(calculatedMac);
|
||||
EXPECT_EQ(mac, calculatedMac);
|
||||
|
||||
// Also perform an additional empty request. This is what mDL applications
|
||||
// are envisioned to do - one call to get the data elements, another to get
|
||||
// an empty DeviceSignedItems and corresponding MAC.
|
||||
//
|
||||
credential->setRequestedNamespaces({}); // OK to fail, not available in v1 HAL
|
||||
ASSERT_TRUE(credential
|
||||
->startRetrieval(
|
||||
secureProfiles.value(), authToken, {}, // itemsRequestBytes
|
||||
signingKeyBlob, sessionTranscriptEncoded, {}, // readerSignature,
|
||||
testEntriesEntryCounts)
|
||||
.isOk());
|
||||
ASSERT_TRUE(credential->finishRetrieval(&mac, &deviceNameSpacesBytes).isOk());
|
||||
cborPretty = support::cborPrettyPrint(deviceNameSpacesBytes, 32, {});
|
||||
ASSERT_EQ("{}", cborPretty);
|
||||
// Calculate DeviceAuthentication and MAC (MACing key hasn't changed)
|
||||
deviceAuthentication = cppbor::Array();
|
||||
deviceAuthentication.add("DeviceAuthentication");
|
||||
deviceAuthentication.add(sessionTranscript.clone());
|
||||
deviceAuthentication.add(docType);
|
||||
deviceAuthentication.add(cppbor::Semantic(24, deviceNameSpacesBytes));
|
||||
deviceAuthenticationBytes = cppbor::Semantic(24, deviceAuthentication.encode()).encode();
|
||||
calculatedMac = support::coseMac0(derivedKey.value(), {}, // payload
|
||||
deviceAuthenticationBytes); // detached content
|
||||
ASSERT_TRUE(calculatedMac);
|
||||
EXPECT_EQ(mac, calculatedMac);
|
||||
|
||||
// Some mDL apps might send a request but with a single empty
|
||||
// namespace. Check that too.
|
||||
RequestNamespace emptyRequestNS;
|
||||
emptyRequestNS.namespaceName = "PersonalData";
|
||||
credential->setRequestedNamespaces({emptyRequestNS}); // OK to fail, not available in v1 HAL
|
||||
ASSERT_TRUE(credential
|
||||
->startRetrieval(
|
||||
secureProfiles.value(), authToken, {}, // itemsRequestBytes
|
||||
signingKeyBlob, sessionTranscriptEncoded, {}, // readerSignature,
|
||||
testEntriesEntryCounts)
|
||||
.isOk());
|
||||
ASSERT_TRUE(credential->finishRetrieval(&mac, &deviceNameSpacesBytes).isOk());
|
||||
cborPretty = support::cborPrettyPrint(deviceNameSpacesBytes, 32, {});
|
||||
ASSERT_EQ("{}", cborPretty);
|
||||
// Calculate DeviceAuthentication and MAC (MACing key hasn't changed)
|
||||
deviceAuthentication = cppbor::Array();
|
||||
deviceAuthentication.add("DeviceAuthentication");
|
||||
deviceAuthentication.add(sessionTranscript.clone());
|
||||
deviceAuthentication.add(docType);
|
||||
deviceAuthentication.add(cppbor::Semantic(24, deviceNameSpacesBytes));
|
||||
deviceAuthenticationBytes = cppbor::Semantic(24, deviceAuthentication.encode()).encode();
|
||||
calculatedMac = support::coseMac0(derivedKey.value(), {}, // payload
|
||||
deviceAuthenticationBytes); // detached content
|
||||
ASSERT_TRUE(calculatedMac);
|
||||
EXPECT_EQ(mac, calculatedMac);
|
||||
}
|
||||
|
||||
@@ -69,11 +69,10 @@ TEST_P(IdentityCredentialTests, verifyAttestationWithEmptyChallenge) {
|
||||
result = writableCredential->getAttestationCertificate(
|
||||
attestationApplicationId, attestationChallenge, &attestationCertificate);
|
||||
|
||||
EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
|
||||
<< endl;
|
||||
|
||||
EXPECT_TRUE(test_utils::validateAttestationCertificate(
|
||||
attestationCertificate, attestationChallenge, attestationApplicationId, hwInfo));
|
||||
EXPECT_FALSE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
|
||||
<< endl;
|
||||
EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
|
||||
EXPECT_EQ(IIdentityCredentialStore::STATUS_INVALID_DATA, result.serviceSpecificErrorCode());
|
||||
}
|
||||
|
||||
TEST_P(IdentityCredentialTests, verifyAttestationSuccessWithChallenge) {
|
||||
@@ -130,6 +129,7 @@ TEST_P(IdentityCredentialTests, verifyStartPersonalization) {
|
||||
|
||||
// First call should go through
|
||||
const vector<int32_t> entryCounts = {2, 4};
|
||||
writableCredential->setExpectedProofOfProvisioningSize(123456);
|
||||
result = writableCredential->startPersonalization(5, entryCounts);
|
||||
ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
|
||||
<< endl;
|
||||
@@ -151,18 +151,8 @@ TEST_P(IdentityCredentialTests, verifyStartPersonalizationMin) {
|
||||
|
||||
// Verify minimal number of profile count and entry count
|
||||
const vector<int32_t> entryCounts = {1, 1};
|
||||
writableCredential->startPersonalization(1, entryCounts);
|
||||
EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
|
||||
<< endl;
|
||||
}
|
||||
|
||||
TEST_P(IdentityCredentialTests, verifyStartPersonalizationZero) {
|
||||
Status result;
|
||||
sp<IWritableIdentityCredential> writableCredential;
|
||||
ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_));
|
||||
|
||||
const vector<int32_t> entryCounts = {0};
|
||||
writableCredential->startPersonalization(0, entryCounts);
|
||||
writableCredential->setExpectedProofOfProvisioningSize(123456);
|
||||
result = writableCredential->startPersonalization(1, entryCounts);
|
||||
EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
|
||||
<< endl;
|
||||
}
|
||||
@@ -174,7 +164,8 @@ TEST_P(IdentityCredentialTests, verifyStartPersonalizationOne) {
|
||||
|
||||
// Verify minimal number of profile count and entry count
|
||||
const vector<int32_t> entryCounts = {1};
|
||||
writableCredential->startPersonalization(1, entryCounts);
|
||||
writableCredential->setExpectedProofOfProvisioningSize(123456);
|
||||
result = writableCredential->startPersonalization(1, entryCounts);
|
||||
EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
|
||||
<< endl;
|
||||
}
|
||||
@@ -186,7 +177,8 @@ TEST_P(IdentityCredentialTests, verifyStartPersonalizationLarge) {
|
||||
|
||||
// Verify set a large number of profile count and entry count is ok
|
||||
const vector<int32_t> entryCounts = {3000};
|
||||
writableCredential->startPersonalization(3500, entryCounts);
|
||||
writableCredential->setExpectedProofOfProvisioningSize(123456);
|
||||
result = writableCredential->startPersonalization(25, entryCounts);
|
||||
EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
|
||||
<< endl;
|
||||
}
|
||||
@@ -198,7 +190,8 @@ TEST_P(IdentityCredentialTests, verifyProfileNumberMismatchShouldFail) {
|
||||
|
||||
// Enter mismatched entry and profile numbers
|
||||
const vector<int32_t> entryCounts = {5, 6};
|
||||
writableCredential->startPersonalization(5, entryCounts);
|
||||
writableCredential->setExpectedProofOfProvisioningSize(123456);
|
||||
result = writableCredential->startPersonalization(5, entryCounts);
|
||||
ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
|
||||
<< endl;
|
||||
|
||||
@@ -234,7 +227,8 @@ TEST_P(IdentityCredentialTests, verifyDuplicateProfileId) {
|
||||
ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_));
|
||||
|
||||
const vector<int32_t> entryCounts = {3, 6};
|
||||
writableCredential->startPersonalization(3, entryCounts);
|
||||
writableCredential->setExpectedProofOfProvisioningSize(123456);
|
||||
result = writableCredential->startPersonalization(3, entryCounts);
|
||||
ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
|
||||
<< endl;
|
||||
|
||||
@@ -251,9 +245,10 @@ TEST_P(IdentityCredentialTests, verifyDuplicateProfileId) {
|
||||
SecureAccessControlProfile profile;
|
||||
Certificate cert;
|
||||
cert.encodedCertificate = testProfile.readerCertificate;
|
||||
int64_t secureUserId = testProfile.userAuthenticationRequired ? 66 : 0;
|
||||
result = writableCredential->addAccessControlProfile(
|
||||
testProfile.id, cert, testProfile.userAuthenticationRequired,
|
||||
testProfile.timeoutMillis, 0, &profile);
|
||||
testProfile.timeoutMillis, secureUserId, &profile);
|
||||
|
||||
if (expectOk) {
|
||||
expectOk = false;
|
||||
@@ -554,7 +549,7 @@ TEST_P(IdentityCredentialTests, verifyEmptyNameSpaceMixedWithNonEmptyWorks) {
|
||||
;
|
||||
// OK to fail, not available in v1 HAL
|
||||
writableCredential->setExpectedProofOfProvisioningSize(expectedPoPSize);
|
||||
writableCredential->startPersonalization(3, entryCounts);
|
||||
result = writableCredential->startPersonalization(3, entryCounts);
|
||||
ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
|
||||
<< endl;
|
||||
|
||||
@@ -608,7 +603,8 @@ TEST_P(IdentityCredentialTests, verifyInterleavingEntryNameSpaceOrderingFails) {
|
||||
// before "Image" and 2 after image, which is not correct. All of same name
|
||||
// space should occur together. Let's see if this fails.
|
||||
const vector<int32_t> entryCounts = {2u, 1u, 2u};
|
||||
writableCredential->startPersonalization(3, entryCounts);
|
||||
writableCredential->setExpectedProofOfProvisioningSize(123456);
|
||||
result = writableCredential->startPersonalization(3, entryCounts);
|
||||
ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
|
||||
<< endl;
|
||||
|
||||
@@ -674,6 +670,7 @@ TEST_P(IdentityCredentialTests, verifyAccessControlProfileIdOutOfRange) {
|
||||
ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_));
|
||||
|
||||
const vector<int32_t> entryCounts = {1};
|
||||
writableCredential->setExpectedProofOfProvisioningSize(123456);
|
||||
Status result = writableCredential->startPersonalization(1, entryCounts);
|
||||
ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
|
||||
<< endl;
|
||||
|
||||
@@ -96,9 +96,10 @@ optional<vector<SecureAccessControlProfile>> addAccessControlProfiles(
|
||||
SecureAccessControlProfile profile;
|
||||
Certificate cert;
|
||||
cert.encodedCertificate = testProfile.readerCertificate;
|
||||
int64_t secureUserId = testProfile.userAuthenticationRequired ? 66 : 0;
|
||||
result = writableCredential->addAccessControlProfile(
|
||||
testProfile.id, cert, testProfile.userAuthenticationRequired,
|
||||
testProfile.timeoutMillis, 0, &profile);
|
||||
testProfile.timeoutMillis, secureUserId, &profile);
|
||||
|
||||
// Don't use assert so all errors can be outputed. Then return
|
||||
// instead of exit even on errors so caller can decide.
|
||||
|
||||
@@ -33,6 +33,7 @@ using ::std::optional;
|
||||
using ::std::string;
|
||||
using ::std::tuple;
|
||||
using ::std::vector;
|
||||
using ::std::pair;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Miscellaneous utilities.
|
||||
@@ -119,6 +120,12 @@ optional<vector<uint8_t>> encryptAes128Gcm(const vector<uint8_t>& key, const vec
|
||||
optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> createEcKeyPairAndAttestation(
|
||||
const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId);
|
||||
|
||||
// Like createEcKeyPairAndAttestation() but allows you to choose the public key.
|
||||
//
|
||||
optional<vector<vector<uint8_t>>> createAttestationForEcPublicKey(
|
||||
const vector<uint8_t>& publicKey, const vector<uint8_t>& challenge,
|
||||
const vector<uint8_t>& applicationId);
|
||||
|
||||
// Creates an 256-bit EC key using the NID_X9_62_prime256v1 curve, returns the
|
||||
// PKCS#8 encoded key-pair.
|
||||
//
|
||||
@@ -134,6 +141,11 @@ optional<vector<uint8_t>> ecKeyPairGetPublicKey(const vector<uint8_t>& keyPair);
|
||||
//
|
||||
optional<vector<uint8_t>> ecKeyPairGetPrivateKey(const vector<uint8_t>& keyPair);
|
||||
|
||||
// Creates a PKCS#8 encoded key-pair from a private key (which must be uncompressed,
|
||||
// e.g. 32 bytes). The public key is derived from the given private key..
|
||||
//
|
||||
optional<vector<uint8_t>> ecPrivateKeyToKeyPair(const vector<uint8_t>& privateKey);
|
||||
|
||||
// For an EC key |keyPair| encoded in PKCS#8 format, creates a PKCS#12 structure
|
||||
// with the key-pair (not using a password to encrypt the data). The public key
|
||||
// in the created structure is included as a certificate, using the given fields
|
||||
@@ -150,6 +162,12 @@ optional<vector<uint8_t>> ecKeyPairGetPkcs12(const vector<uint8_t>& keyPair, con
|
||||
//
|
||||
optional<vector<uint8_t>> signEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data);
|
||||
|
||||
// Like signEcDsa() but instead of taking the data to be signed, takes a digest
|
||||
// of it instead.
|
||||
//
|
||||
optional<vector<uint8_t>> signEcDsaDigest(const vector<uint8_t>& key,
|
||||
const vector<uint8_t>& dataDigest);
|
||||
|
||||
// Calculates the HMAC with SHA-256 for |data| using |key|. The calculated HMAC
|
||||
// is returned and will be 32 bytes.
|
||||
//
|
||||
@@ -170,6 +188,27 @@ bool checkEcDsaSignature(const vector<uint8_t>& digest, const vector<uint8_t>& s
|
||||
//
|
||||
optional<vector<uint8_t>> certificateChainGetTopMostKey(const vector<uint8_t>& certificateChain);
|
||||
|
||||
// Extracts the public-key from the top-most certificate in |certificateChain|
|
||||
// (which should be a concatenated chain of DER-encoded X.509 certificates).
|
||||
//
|
||||
// Return offset and size of the public-key
|
||||
//
|
||||
optional<pair<size_t, size_t>> certificateFindPublicKey(const vector<uint8_t>& x509Certificate);
|
||||
|
||||
// Extracts the TbsCertificate from the top-most certificate in |certificateChain|
|
||||
// (which should be a concatenated chain of DER-encoded X.509 certificates).
|
||||
//
|
||||
// Return offset and size of the TbsCertificate
|
||||
//
|
||||
optional<pair<size_t, size_t>> certificateTbsCertificate(const vector<uint8_t>& x509Certificate);
|
||||
|
||||
// Extracts the Signature from the top-most certificate in |certificateChain|
|
||||
// (which should be a concatenated chain of DER-encoded X.509 certificates).
|
||||
//
|
||||
// Return offset and size of the Signature
|
||||
//
|
||||
optional<pair<size_t, size_t>> certificateFindSignature(const vector<uint8_t>& x509Certificate);
|
||||
|
||||
// Generates a X.509 certificate for |publicKey| (which must be in the format
|
||||
// returned by ecKeyPairGetPublicKey()).
|
||||
//
|
||||
@@ -226,6 +265,11 @@ optional<vector<vector<uint8_t>>> certificateChainSplit(const vector<uint8_t>& c
|
||||
//
|
||||
bool certificateChainValidate(const vector<uint8_t>& certificateChain);
|
||||
|
||||
// Returns true if |certificate| is signed by |publicKey|.
|
||||
//
|
||||
bool certificateSignedByPublicKey(const vector<uint8_t>& certificate,
|
||||
const vector<uint8_t>& publicKey);
|
||||
|
||||
// Signs |data| and |detachedContent| with |key| (which must be in the format
|
||||
// returned by ecKeyPairGetPrivateKey()).
|
||||
//
|
||||
@@ -238,6 +282,21 @@ optional<vector<uint8_t>> coseSignEcDsa(const vector<uint8_t>& key, const vector
|
||||
const vector<uint8_t>& detachedContent,
|
||||
const vector<uint8_t>& certificateChain);
|
||||
|
||||
// Creates a COSE_Signature1 where |signatureToBeSigned| is the ECDSA signature
|
||||
// of the ToBeSigned CBOR from RFC 8051 "4.4. Signing and Verification Process".
|
||||
//
|
||||
// The |signatureToBeSigned| is expected to be 64 bytes and contain the R value,
|
||||
// then the S value.
|
||||
//
|
||||
// The |data| parameter will be included in the COSE_Sign1 CBOR.
|
||||
//
|
||||
// If |certificateChain| is non-empty it's included in the 'x5chain'
|
||||
// protected header element (as as described in'draft-ietf-cose-x509-04').
|
||||
//
|
||||
optional<vector<uint8_t>> coseSignEcDsaWithSignature(const vector<uint8_t>& signatureToBeSigned,
|
||||
const vector<uint8_t>& data,
|
||||
const vector<uint8_t>& certificateChain);
|
||||
|
||||
// Checks that |signatureCoseSign1| (in COSE_Sign1 format) is a valid signature
|
||||
// made with |public_key| (which must be in the format returned by
|
||||
// ecKeyPairGetPublicKey()) where |detachedContent| is the detached content.
|
||||
@@ -246,9 +305,23 @@ bool coseCheckEcDsaSignature(const vector<uint8_t>& signatureCoseSign1,
|
||||
const vector<uint8_t>& detachedContent,
|
||||
const vector<uint8_t>& publicKey);
|
||||
|
||||
// Converts a DER-encoded signature to the format used in 'signature' bstr in COSE_Sign1.
|
||||
bool ecdsaSignatureDerToCose(const vector<uint8_t>& ecdsaDerSignature,
|
||||
vector<uint8_t>& ecdsaCoseSignature);
|
||||
|
||||
// Converts from the format in in 'signature' bstr in COSE_Sign1 to DER encoding.
|
||||
bool ecdsaSignatureCoseToDer(const vector<uint8_t>& ecdsaCoseSignature,
|
||||
vector<uint8_t>& ecdsaDerSignature);
|
||||
|
||||
// Extracts the payload from a COSE_Sign1.
|
||||
optional<vector<uint8_t>> coseSignGetPayload(const vector<uint8_t>& signatureCoseSign1);
|
||||
|
||||
// Extracts the signature (of the ToBeSigned CBOR) from a COSE_Sign1.
|
||||
optional<vector<uint8_t>> coseSignGetSignature(const vector<uint8_t>& signatureCoseSign1);
|
||||
|
||||
// Extracts the signature algorithm from a COSE_Sign1.
|
||||
optional<int> coseSignGetAlg(const vector<uint8_t>& signatureCoseSign1);
|
||||
|
||||
// Extracts the X.509 certificate chain, if present. Returns the data as a
|
||||
// concatenated chain of DER-encoded X.509 certificates
|
||||
//
|
||||
@@ -264,6 +337,16 @@ optional<vector<uint8_t>> coseSignGetX5Chain(const vector<uint8_t>& signatureCos
|
||||
optional<vector<uint8_t>> coseMac0(const vector<uint8_t>& key, const vector<uint8_t>& data,
|
||||
const vector<uint8_t>& detachedContent);
|
||||
|
||||
// Creates a COSE_Mac0 where |digestToBeMaced| is the HMAC-SHA256
|
||||
// of the ToBeMaced CBOR from RFC 8051 "6.3. How to Compute and Verify a MAC".
|
||||
//
|
||||
// The |digestToBeMaced| is expected to be 32 bytes.
|
||||
//
|
||||
// The |data| parameter will be included in the COSE_Mac0 CBOR.
|
||||
//
|
||||
optional<vector<uint8_t>> coseMacWithDigest(const vector<uint8_t>& digestToBeMaced,
|
||||
const vector<uint8_t>& data);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Utility functions specific to IdentityCredential.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <chrono>
|
||||
#include <iomanip>
|
||||
|
||||
#include <openssl/aes.h>
|
||||
@@ -684,6 +685,48 @@ static bool parseX509Certificates(const vector<uint8_t>& certificateChain,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool certificateSignedByPublicKey(const vector<uint8_t>& certificate,
|
||||
const vector<uint8_t>& publicKey) {
|
||||
const unsigned char* p = certificate.data();
|
||||
auto x509 = X509_Ptr(d2i_X509(nullptr, &p, certificate.size()));
|
||||
if (x509 == nullptr) {
|
||||
LOG(ERROR) << "Error parsing X509 certificate";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
|
||||
auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
|
||||
if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
|
||||
1) {
|
||||
LOG(ERROR) << "Error decoding publicKey";
|
||||
return false;
|
||||
}
|
||||
auto ecKey = EC_KEY_Ptr(EC_KEY_new());
|
||||
auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
|
||||
if (ecKey.get() == nullptr || pkey.get() == nullptr) {
|
||||
LOG(ERROR) << "Memory allocation failed";
|
||||
return false;
|
||||
}
|
||||
if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
|
||||
LOG(ERROR) << "Error setting group";
|
||||
return false;
|
||||
}
|
||||
if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
|
||||
LOG(ERROR) << "Error setting point";
|
||||
return false;
|
||||
}
|
||||
if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
|
||||
LOG(ERROR) << "Error setting key";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (X509_verify(x509.get(), pkey.get()) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: Right now the only check we perform is to check that each certificate
|
||||
// is signed by its successor. We should - but currently don't - also check
|
||||
// things like valid dates etc.
|
||||
@@ -770,7 +813,8 @@ vector<uint8_t> sha256(const vector<uint8_t>& data) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
optional<vector<uint8_t>> signEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data) {
|
||||
optional<vector<uint8_t>> signEcDsaDigest(const vector<uint8_t>& key,
|
||||
const vector<uint8_t>& dataDigest) {
|
||||
auto bn = BIGNUM_Ptr(BN_bin2bn(key.data(), key.size(), nullptr));
|
||||
if (bn.get() == nullptr) {
|
||||
LOG(ERROR) << "Error creating BIGNUM";
|
||||
@@ -783,8 +827,7 @@ optional<vector<uint8_t>> signEcDsa(const vector<uint8_t>& key, const vector<uin
|
||||
return {};
|
||||
}
|
||||
|
||||
auto digest = sha256(data);
|
||||
ECDSA_SIG* sig = ECDSA_do_sign(digest.data(), digest.size(), ec_key.get());
|
||||
ECDSA_SIG* sig = ECDSA_do_sign(dataDigest.data(), dataDigest.size(), ec_key.get());
|
||||
if (sig == nullptr) {
|
||||
LOG(ERROR) << "Error signing digest";
|
||||
return {};
|
||||
@@ -798,6 +841,10 @@ optional<vector<uint8_t>> signEcDsa(const vector<uint8_t>& key, const vector<uin
|
||||
return signature;
|
||||
}
|
||||
|
||||
optional<vector<uint8_t>> signEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data) {
|
||||
return signEcDsaDigest(key, sha256(data));
|
||||
}
|
||||
|
||||
optional<vector<uint8_t>> hmacSha256(const vector<uint8_t>& key, const vector<uint8_t>& data) {
|
||||
HMAC_CTX ctx;
|
||||
HMAC_CTX_init(&ctx);
|
||||
@@ -955,6 +1002,51 @@ optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> createEcKeyPairAnd
|
||||
return make_pair(keyPair, attestationCert.value());
|
||||
}
|
||||
|
||||
optional<vector<vector<uint8_t>>> createAttestationForEcPublicKey(
|
||||
const vector<uint8_t>& publicKey, const vector<uint8_t>& challenge,
|
||||
const vector<uint8_t>& applicationId) {
|
||||
auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
|
||||
auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
|
||||
if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
|
||||
1) {
|
||||
LOG(ERROR) << "Error decoding publicKey";
|
||||
return {};
|
||||
}
|
||||
auto ecKey = EC_KEY_Ptr(EC_KEY_new());
|
||||
auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
|
||||
if (ecKey.get() == nullptr || pkey.get() == nullptr) {
|
||||
LOG(ERROR) << "Memory allocation failed";
|
||||
return {};
|
||||
}
|
||||
if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
|
||||
LOG(ERROR) << "Error setting group";
|
||||
return {};
|
||||
}
|
||||
if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
|
||||
LOG(ERROR) << "Error setting point";
|
||||
return {};
|
||||
}
|
||||
if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
|
||||
LOG(ERROR) << "Error setting key";
|
||||
return {};
|
||||
}
|
||||
|
||||
uint64_t now = (std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch()).
|
||||
count()/ 1000000000);
|
||||
uint64_t secondsInOneYear = 365 * 24 * 60 * 60;
|
||||
uint64_t expireTimeMs = (now + secondsInOneYear) * 1000;
|
||||
|
||||
optional<vector<vector<uint8_t>>> attestationCert =
|
||||
createAttestation(pkey.get(), applicationId, challenge, now * 1000, expireTimeMs);
|
||||
if (!attestationCert) {
|
||||
LOG(ERROR) << "Error create attestation from key and challenge";
|
||||
return {};
|
||||
}
|
||||
|
||||
return attestationCert.value();
|
||||
}
|
||||
|
||||
optional<vector<uint8_t>> createEcKeyPair() {
|
||||
auto ec_key = EC_KEY_Ptr(EC_KEY_new());
|
||||
auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
|
||||
@@ -1047,6 +1139,42 @@ optional<vector<uint8_t>> ecKeyPairGetPrivateKey(const vector<uint8_t>& keyPair)
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
optional<vector<uint8_t>> ecPrivateKeyToKeyPair(const vector<uint8_t>& privateKey) {
|
||||
auto bn = BIGNUM_Ptr(BN_bin2bn(privateKey.data(), privateKey.size(), nullptr));
|
||||
if (bn.get() == nullptr) {
|
||||
LOG(ERROR) << "Error creating BIGNUM";
|
||||
return {};
|
||||
}
|
||||
|
||||
auto ecKey = EC_KEY_Ptr(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
|
||||
if (EC_KEY_set_private_key(ecKey.get(), bn.get()) != 1) {
|
||||
LOG(ERROR) << "Error setting private key from BIGNUM";
|
||||
return {};
|
||||
}
|
||||
|
||||
auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
|
||||
if (pkey.get() == nullptr) {
|
||||
LOG(ERROR) << "Memory allocation failed";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
|
||||
LOG(ERROR) << "Error getting private key";
|
||||
return {};
|
||||
}
|
||||
|
||||
int size = i2d_PrivateKey(pkey.get(), nullptr);
|
||||
if (size == 0) {
|
||||
LOG(ERROR) << "Error generating public key encoding";
|
||||
return {};
|
||||
}
|
||||
vector<uint8_t> keyPair;
|
||||
keyPair.resize(size);
|
||||
unsigned char* p = keyPair.data();
|
||||
i2d_PrivateKey(pkey.get(), &p);
|
||||
return keyPair;
|
||||
}
|
||||
|
||||
optional<vector<uint8_t>> ecKeyPairGetPkcs12(const vector<uint8_t>& keyPair, const string& name,
|
||||
const string& serialDecimal, const string& issuer,
|
||||
const string& subject, time_t validityNotBefore,
|
||||
@@ -1441,6 +1569,120 @@ optional<vector<uint8_t>> certificateChainGetTopMostKey(const vector<uint8_t>& c
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
optional<pair<size_t, size_t>> certificateFindPublicKey(const vector<uint8_t>& x509Certificate) {
|
||||
vector<X509_Ptr> certs;
|
||||
if (!parseX509Certificates(x509Certificate, certs)) {
|
||||
return {};
|
||||
}
|
||||
if (certs.size() < 1) {
|
||||
LOG(ERROR) << "No certificates in chain";
|
||||
return {};
|
||||
}
|
||||
|
||||
auto pkey = EVP_PKEY_Ptr(X509_get_pubkey(certs[0].get()));
|
||||
if (pkey.get() == nullptr) {
|
||||
LOG(ERROR) << "No public key";
|
||||
return {};
|
||||
}
|
||||
|
||||
auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pkey.get()));
|
||||
if (ecKey.get() == nullptr) {
|
||||
LOG(ERROR) << "Failed getting EC key";
|
||||
return {};
|
||||
}
|
||||
|
||||
auto ecGroup = EC_KEY_get0_group(ecKey.get());
|
||||
auto ecPoint = EC_KEY_get0_public_key(ecKey.get());
|
||||
int size = EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0,
|
||||
nullptr);
|
||||
if (size == 0) {
|
||||
LOG(ERROR) << "Error generating public key encoding";
|
||||
return {};
|
||||
}
|
||||
vector<uint8_t> publicKey;
|
||||
publicKey.resize(size);
|
||||
EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, publicKey.data(),
|
||||
publicKey.size(), nullptr);
|
||||
|
||||
size_t publicKeyOffset = 0;
|
||||
size_t publicKeySize = (size_t)size;
|
||||
void* location = memmem((const void*)x509Certificate.data(), x509Certificate.size(),
|
||||
(const void*)publicKey.data(), publicKey.size());
|
||||
|
||||
if (location == NULL) {
|
||||
LOG(ERROR) << "Error finding publicKey from x509Certificate";
|
||||
return {};
|
||||
}
|
||||
publicKeyOffset = (size_t)((const char*)location - (const char*)x509Certificate.data());
|
||||
|
||||
return std::make_pair(publicKeyOffset, publicKeySize);
|
||||
}
|
||||
|
||||
optional<pair<size_t, size_t>> certificateTbsCertificate(const vector<uint8_t>& x509Certificate) {
|
||||
vector<X509_Ptr> certs;
|
||||
if (!parseX509Certificates(x509Certificate, certs)) {
|
||||
return {};
|
||||
}
|
||||
if (certs.size() < 1) {
|
||||
LOG(ERROR) << "No certificates in chain";
|
||||
return {};
|
||||
}
|
||||
|
||||
unsigned char* buf = NULL;
|
||||
int len = i2d_re_X509_tbs(certs[0].get(), &buf);
|
||||
if ((len < 0) || (buf == NULL)) {
|
||||
LOG(ERROR) << "fail to extract tbsCertificate in x509Certificate";
|
||||
return {};
|
||||
}
|
||||
|
||||
vector<uint8_t> tbsCertificate(len);
|
||||
memcpy(tbsCertificate.data(), buf, len);
|
||||
|
||||
size_t tbsCertificateOffset = 0;
|
||||
size_t tbsCertificateSize = (size_t)len;
|
||||
void* location = memmem((const void*)x509Certificate.data(), x509Certificate.size(),
|
||||
(const void*)tbsCertificate.data(), tbsCertificate.size());
|
||||
|
||||
if (location == NULL) {
|
||||
LOG(ERROR) << "Error finding tbsCertificate from x509Certificate";
|
||||
return {};
|
||||
}
|
||||
tbsCertificateOffset = (size_t)((const char*)location - (const char*)x509Certificate.data());
|
||||
|
||||
return std::make_pair(tbsCertificateOffset, tbsCertificateSize);
|
||||
}
|
||||
|
||||
optional<pair<size_t, size_t>> certificateFindSignature(const vector<uint8_t>& x509Certificate) {
|
||||
vector<X509_Ptr> certs;
|
||||
if (!parseX509Certificates(x509Certificate, certs)) {
|
||||
return {};
|
||||
}
|
||||
if (certs.size() < 1) {
|
||||
LOG(ERROR) << "No certificates in chain";
|
||||
return {};
|
||||
}
|
||||
|
||||
ASN1_BIT_STRING* psig;
|
||||
X509_ALGOR* palg;
|
||||
X509_get0_signature((const ASN1_BIT_STRING**)&psig, (const X509_ALGOR**)&palg, certs[0].get());
|
||||
|
||||
vector<char> signature(psig->length);
|
||||
memcpy(signature.data(), psig->data, psig->length);
|
||||
|
||||
size_t signatureOffset = 0;
|
||||
size_t signatureSize = (size_t)psig->length;
|
||||
void* location = memmem((const void*)x509Certificate.data(), x509Certificate.size(),
|
||||
(const void*)signature.data(), signature.size());
|
||||
|
||||
if (location == NULL) {
|
||||
LOG(ERROR) << "Error finding signature from x509Certificate";
|
||||
return {};
|
||||
}
|
||||
signatureOffset = (size_t)((const char*)location - (const char*)x509Certificate.data());
|
||||
|
||||
return std::make_pair(signatureOffset, signatureSize);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// COSE Utility Functions
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -1538,6 +1780,55 @@ bool ecdsaSignatureDerToCose(const vector<uint8_t>& ecdsaDerSignature,
|
||||
return true;
|
||||
}
|
||||
|
||||
optional<vector<uint8_t>> coseSignEcDsaWithSignature(const vector<uint8_t>& signatureToBeSigned,
|
||||
const vector<uint8_t>& data,
|
||||
const vector<uint8_t>& certificateChain) {
|
||||
if (signatureToBeSigned.size() != 64) {
|
||||
LOG(ERROR) << "Invalid size for signatureToBeSigned, expected 64 got "
|
||||
<< signatureToBeSigned.size();
|
||||
return {};
|
||||
}
|
||||
|
||||
cppbor::Map unprotectedHeaders;
|
||||
cppbor::Map protectedHeaders;
|
||||
|
||||
protectedHeaders.add(COSE_LABEL_ALG, COSE_ALG_ECDSA_256);
|
||||
|
||||
if (certificateChain.size() != 0) {
|
||||
optional<vector<vector<uint8_t>>> certs = support::certificateChainSplit(certificateChain);
|
||||
if (!certs) {
|
||||
LOG(ERROR) << "Error splitting certificate chain";
|
||||
return {};
|
||||
}
|
||||
if (certs.value().size() == 1) {
|
||||
unprotectedHeaders.add(COSE_LABEL_X5CHAIN, certs.value()[0]);
|
||||
} else {
|
||||
cppbor::Array certArray;
|
||||
for (const vector<uint8_t>& cert : certs.value()) {
|
||||
certArray.add(cert);
|
||||
}
|
||||
unprotectedHeaders.add(COSE_LABEL_X5CHAIN, std::move(certArray));
|
||||
}
|
||||
}
|
||||
|
||||
vector<uint8_t> encodedProtectedHeaders = coseEncodeHeaders(protectedHeaders);
|
||||
|
||||
cppbor::Array coseSign1;
|
||||
coseSign1.add(encodedProtectedHeaders);
|
||||
coseSign1.add(std::move(unprotectedHeaders));
|
||||
if (data.size() == 0) {
|
||||
cppbor::Null nullValue;
|
||||
coseSign1.add(std::move(nullValue));
|
||||
} else {
|
||||
coseSign1.add(data);
|
||||
}
|
||||
coseSign1.add(signatureToBeSigned);
|
||||
vector<uint8_t> signatureCoseSign1;
|
||||
signatureCoseSign1 = coseSign1.encode();
|
||||
|
||||
return signatureCoseSign1;
|
||||
}
|
||||
|
||||
optional<vector<uint8_t>> coseSignEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data,
|
||||
const vector<uint8_t>& detachedContent,
|
||||
const vector<uint8_t>& certificateChain) {
|
||||
@@ -1673,6 +1964,35 @@ bool coseCheckEcDsaSignature(const vector<uint8_t>& signatureCoseSign1,
|
||||
return true;
|
||||
}
|
||||
|
||||
// Extracts the signature (of the ToBeSigned CBOR) from a COSE_Sign1.
|
||||
optional<vector<uint8_t>> coseSignGetSignature(const vector<uint8_t>& signatureCoseSign1) {
|
||||
auto [item, _, message] = cppbor::parse(signatureCoseSign1);
|
||||
if (item == nullptr) {
|
||||
LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
|
||||
return {};
|
||||
}
|
||||
const cppbor::Array* array = item->asArray();
|
||||
if (array == nullptr) {
|
||||
LOG(ERROR) << "Value for COSE_Sign1 is not an array";
|
||||
return {};
|
||||
}
|
||||
if (array->size() != 4) {
|
||||
LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
|
||||
return {};
|
||||
}
|
||||
|
||||
vector<uint8_t> signature;
|
||||
const cppbor::Bstr* signatureAsBstr = (*array)[3]->asBstr();
|
||||
if (signatureAsBstr == nullptr) {
|
||||
LOG(ERROR) << "Value for signature is not a bstr";
|
||||
return {};
|
||||
}
|
||||
// Copy payload into |data|
|
||||
signature = signatureAsBstr->value();
|
||||
|
||||
return signature;
|
||||
}
|
||||
|
||||
optional<vector<uint8_t>> coseSignGetPayload(const vector<uint8_t>& signatureCoseSign1) {
|
||||
auto [item, _, message] = cppbor::parse(signatureCoseSign1);
|
||||
if (item == nullptr) {
|
||||
@@ -1710,6 +2030,59 @@ optional<vector<uint8_t>> coseSignGetPayload(const vector<uint8_t>& signatureCos
|
||||
return data;
|
||||
}
|
||||
|
||||
optional<int> coseSignGetAlg(const vector<uint8_t>& signatureCoseSign1) {
|
||||
auto [item, _, message] = cppbor::parse(signatureCoseSign1);
|
||||
if (item == nullptr) {
|
||||
LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
|
||||
return {};
|
||||
}
|
||||
const cppbor::Array* array = item->asArray();
|
||||
if (array == nullptr) {
|
||||
LOG(ERROR) << "Value for COSE_Sign1 is not an array";
|
||||
return {};
|
||||
}
|
||||
if (array->size() != 4) {
|
||||
LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
|
||||
return {};
|
||||
}
|
||||
|
||||
const cppbor::Bstr* protectedHeadersBytes = (*array)[0]->asBstr();
|
||||
if (protectedHeadersBytes == nullptr) {
|
||||
LOG(ERROR) << "Value for protectedHeaders is not a bstr";
|
||||
return {};
|
||||
}
|
||||
auto [item2, _2, message2] = cppbor::parse(protectedHeadersBytes->value());
|
||||
if (item2 == nullptr) {
|
||||
LOG(ERROR) << "Error parsing protectedHeaders: " << message2;
|
||||
return {};
|
||||
}
|
||||
const cppbor::Map* protectedHeaders = item2->asMap();
|
||||
if (protectedHeaders == nullptr) {
|
||||
LOG(ERROR) << "Decoded CBOR for protectedHeaders is not a map";
|
||||
return {};
|
||||
}
|
||||
|
||||
for (size_t n = 0; n < protectedHeaders->size(); n++) {
|
||||
auto [keyItem, valueItem] = (*protectedHeaders)[n];
|
||||
const cppbor::Int* number = keyItem->asInt();
|
||||
if (number == nullptr) {
|
||||
LOG(ERROR) << "Key item in top-level map is not a number";
|
||||
return {};
|
||||
}
|
||||
int label = number->value();
|
||||
if (label == COSE_LABEL_ALG) {
|
||||
const cppbor::Int* number = valueItem->asInt();
|
||||
if (number != nullptr) {
|
||||
return number->value();
|
||||
}
|
||||
LOG(ERROR) << "Value for COSE_LABEL_ALG label is not a number";
|
||||
return {};
|
||||
}
|
||||
}
|
||||
LOG(ERROR) << "Did not find COSE_LABEL_ALG label in protected headers";
|
||||
return {};
|
||||
}
|
||||
|
||||
optional<vector<uint8_t>> coseSignGetX5Chain(const vector<uint8_t>& signatureCoseSign1) {
|
||||
auto [item, _, message] = cppbor::parse(signatureCoseSign1);
|
||||
if (item == nullptr) {
|
||||
@@ -1825,6 +2198,28 @@ optional<vector<uint8_t>> coseMac0(const vector<uint8_t>& key, const vector<uint
|
||||
return array.encode();
|
||||
}
|
||||
|
||||
optional<vector<uint8_t>> coseMacWithDigest(const vector<uint8_t>& digestToBeMaced,
|
||||
const vector<uint8_t>& data) {
|
||||
cppbor::Map unprotectedHeaders;
|
||||
cppbor::Map protectedHeaders;
|
||||
|
||||
protectedHeaders.add(COSE_LABEL_ALG, COSE_ALG_HMAC_256_256);
|
||||
|
||||
vector<uint8_t> encodedProtectedHeaders = coseEncodeHeaders(protectedHeaders);
|
||||
|
||||
cppbor::Array array;
|
||||
array.add(encodedProtectedHeaders);
|
||||
array.add(std::move(unprotectedHeaders));
|
||||
if (data.size() == 0) {
|
||||
cppbor::Null nullValue;
|
||||
array.add(std::move(nullValue));
|
||||
} else {
|
||||
array.add(data);
|
||||
}
|
||||
array.add(digestToBeMaced);
|
||||
return array.encode();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Utility functions specific to IdentityCredential.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -121,8 +121,8 @@ void appendUint64(std::vector<uint8_t>& vec, uint64_t value) {
|
||||
uint64_t extractUint64(const std::vector<uint8_t>& data, size_t offset) {
|
||||
uint64_t value = 0;
|
||||
for (size_t n = 0; n < sizeof(uint64_t); n++) {
|
||||
uint8_t byte = data[offset + n];
|
||||
value |= byte << (n * 8);
|
||||
uint64_t tmp = data[offset + n];
|
||||
value |= (tmp << (n * 8));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@@ -137,8 +137,8 @@ void appendUint32(std::vector<uint8_t>& vec, uint32_t value) {
|
||||
uint32_t extractUint32(const std::vector<uint8_t>& data, size_t offset) {
|
||||
uint32_t value = 0;
|
||||
for (size_t n = 0; n < sizeof(uint32_t); n++) {
|
||||
uint8_t byte = data[offset + n];
|
||||
value |= byte << (n * 8);
|
||||
uint32_t tmp = data[offset + n];
|
||||
value |= (tmp << (n * 8));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -438,10 +438,10 @@ bool verify_attestation_record(const string& challenge, const string& app_id,
|
||||
EXPECT_TRUE(device_locked);
|
||||
}
|
||||
|
||||
// Check that the expected result from VBMeta matches the build type. Only a user build
|
||||
// should have AVB reporting the device is locked.
|
||||
EXPECT_NE(property_get("ro.build.type", property_value, ""), 0);
|
||||
if (!strcmp(property_value, "user")) {
|
||||
// Check that the device is locked if not debuggable, e.g., user build
|
||||
// images in CTS. For VTS, debuggable images are used to allow adb root
|
||||
// and the device is unlocked.
|
||||
if (!property_get_bool("ro.debuggable", false)) {
|
||||
EXPECT_TRUE(device_locked);
|
||||
} else {
|
||||
EXPECT_FALSE(device_locked);
|
||||
|
||||
@@ -74,5 +74,6 @@ cc_defaults {
|
||||
// TODO(b/64437680): Assume these libs are always available on the device.
|
||||
shared_libs: [
|
||||
"libstagefright_foundation",
|
||||
"libstagefright_omx_utils",
|
||||
],
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <hidl/GtestPrinter.h>
|
||||
#include <hidl/ServiceManagement.h>
|
||||
#include <media/stagefright/omx/OMXUtils.h>
|
||||
|
||||
using ::android::sp;
|
||||
using ::android::base::Join;
|
||||
@@ -87,71 +88,6 @@ void displayComponentInfo(hidl_vec<IOmx::ComponentInfo>& nodeList) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the role based on is_encoder and mime.
|
||||
*
|
||||
* The mapping from a pair (is_encoder, mime) to a role string is
|
||||
* defined in frameworks/av/media/libmedia/MediaDefs.cpp and
|
||||
* frameworks/av/media/libstagefright/omx/OMXUtils.cpp. This function
|
||||
* does essentially the same work as GetComponentRole() in
|
||||
* OMXUtils.cpp.
|
||||
*
|
||||
* Args:
|
||||
* is_encoder: A boolean indicating whether the role is for an
|
||||
* encoder or a decoder.
|
||||
* mime: A string of the desired mime type.
|
||||
*
|
||||
* Returns:
|
||||
* A const string for the requested role name, empty if mime is not
|
||||
* recognized.
|
||||
*/
|
||||
const std::string getComponentRole(bool isEncoder, const std::string mime) {
|
||||
// Mapping from mime types to roles.
|
||||
// These values come from MediaDefs.cpp and OMXUtils.cpp
|
||||
const std::map<const std::string, const std::string> audioMimeToRole = {
|
||||
{"3gpp", "amrnb"}, {"ac3", "ac3"}, {"amr-wb", "amrwb"},
|
||||
{"eac3", "eac3"}, {"flac", "flac"}, {"g711-alaw", "g711alaw"},
|
||||
{"g711-mlaw", "g711mlaw"}, {"gsm", "gsm"}, {"mp4a-latm", "aac"},
|
||||
{"mpeg", "mp3"}, {"mpeg-L1", "mp1"}, {"mpeg-L2", "mp2"},
|
||||
{"opus", "opus"}, {"raw", "raw"}, {"vorbis", "vorbis"},
|
||||
};
|
||||
const std::map<const std::string, const std::string> videoMimeToRole = {
|
||||
{"3gpp", "h263"}, {"avc", "avc"}, {"dolby-vision", "dolby-vision"},
|
||||
{"hevc", "hevc"}, {"mp4v-es", "mpeg4"}, {"mpeg2", "mpeg2"},
|
||||
{"x-vnd.on2.vp8", "vp8"}, {"x-vnd.on2.vp9", "vp9"},
|
||||
};
|
||||
const std::map<const std::string, const std::string> imageMimeToRole = {
|
||||
{"vnd.android.heic", "heic"},
|
||||
};
|
||||
|
||||
// Suffix begins after the mime prefix.
|
||||
const size_t prefixEnd = mime.find("/");
|
||||
if (prefixEnd == std::string::npos || prefixEnd == mime.size()) return "";
|
||||
const std::string mime_suffix = mime.substr(prefixEnd + 1, mime.size() - 1);
|
||||
const std::string middle = isEncoder ? "encoder." : "decoder.";
|
||||
std::string prefix;
|
||||
std::string suffix;
|
||||
if (mime.rfind("audio/", 0) != std::string::npos) {
|
||||
const auto it = audioMimeToRole.find(mime_suffix);
|
||||
if (it == audioMimeToRole.end()) return "";
|
||||
prefix = "audio_";
|
||||
suffix = it->second;
|
||||
} else if (mime.rfind("video/", 0) != std::string::npos) {
|
||||
const auto it = videoMimeToRole.find(mime_suffix);
|
||||
if (it == videoMimeToRole.end()) return "";
|
||||
prefix = "video_";
|
||||
suffix = it->second;
|
||||
} else if (mime.rfind("image/", 0) != std::string::npos) {
|
||||
const auto it = imageMimeToRole.find(mime_suffix);
|
||||
if (it == imageMimeToRole.end()) return "";
|
||||
prefix = "image_";
|
||||
suffix = it->second;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
return prefix + middle + suffix;
|
||||
}
|
||||
|
||||
void validateAttributes(
|
||||
const std::map<const std::string, const testing::internal::RE>& knownPatterns,
|
||||
const std::vector<const struct AttributePattern>& unknownPatterns,
|
||||
@@ -315,7 +251,7 @@ TEST_P(MasterHidlTest, ListRoles) {
|
||||
};
|
||||
|
||||
// Matching rules for node names and owners
|
||||
const testing::internal::RE nodeNamePattern = "[a-zA-Z0-9.-]+";
|
||||
const testing::internal::RE nodeNamePattern = "[a-zA-Z0-9._-]+";
|
||||
const testing::internal::RE nodeOwnerPattern = "[a-zA-Z0-9._-]+";
|
||||
|
||||
std::set<const std::string> roleKeys;
|
||||
@@ -328,7 +264,8 @@ TEST_P(MasterHidlTest, ListRoles) {
|
||||
|
||||
// Make sure role name follows expected format based on type and
|
||||
// isEncoder
|
||||
const std::string role_name = getComponentRole(role.isEncoder, role.type);
|
||||
const std::string role_name(
|
||||
::android::GetComponentRole(role.isEncoder, role.type.c_str()));
|
||||
EXPECT_EQ(role_name, role.role) << "Role \"" << role.role << "\" does not match "
|
||||
<< (role.isEncoder ? "an encoder " : "a decoder ")
|
||||
<< "for mime type \"" << role.type << ".";
|
||||
|
||||
@@ -62,11 +62,12 @@ cc_test {
|
||||
defaults: ["neuralnetworks_vts_functional_defaults"],
|
||||
srcs: [
|
||||
"BasicTests.cpp",
|
||||
"GeneratedTestHarness.cpp",
|
||||
"TestAssertions.cpp",
|
||||
"TestMain.cpp",
|
||||
"ValidateModel.cpp",
|
||||
"ValidateRequest.cpp",
|
||||
"VtsHalNeuralnetworks.cpp",
|
||||
"GeneratedTestHarness.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libfmq",
|
||||
|
||||
@@ -26,10 +26,6 @@
|
||||
</target_preparer>
|
||||
|
||||
<test class="com.android.tradefed.testtype.GTest" >
|
||||
<!-- b/155577050, temporarily disable the failing tests.
|
||||
Must be deleted after corresponding driver issues are fixed.
|
||||
-->
|
||||
<option name="native-test-flag" value="--gtest_filter=-*Validation*:*CycleTest*:*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*" />
|
||||
<option name="native-test-device-path" value="/data/local/tmp" />
|
||||
<option name="module-name" value="VtsHalNeuralnetworksV1_0TargetTest" />
|
||||
</test>
|
||||
|
||||
25
neuralnetworks/1.0/vts/functional/TestMain.cpp
Normal file
25
neuralnetworks/1.0/vts/functional/TestMain.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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 <gtest/gtest.h>
|
||||
#include "1.0/LogTestCaseToLogcat.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
testing::UnitTest::GetInstance()->listeners().Append(
|
||||
new android::hardware::neuralnetworks::LogTestCaseToLogcat());
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_0_LOG_TEST_CASE_TO_LOGCAT_H
|
||||
#define ANDROID_HARDWARE_NEURALNETWORKS_V1_0_LOG_TEST_CASE_TO_LOGCAT_H
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace android::hardware::neuralnetworks {
|
||||
|
||||
class LogTestCaseToLogcat : public ::testing::EmptyTestEventListener {
|
||||
public:
|
||||
void OnTestStart(const ::testing::TestInfo& test_info) override {
|
||||
LOG(INFO) << "[Test Case] " << test_info.test_suite_name() << "." << test_info.name()
|
||||
<< " BEGIN";
|
||||
}
|
||||
|
||||
void OnTestEnd(const ::testing::TestInfo& test_info) override {
|
||||
LOG(INFO) << "[Test Case] " << test_info.test_suite_name() << "." << test_info.name()
|
||||
<< " END";
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace android::hardware::neuralnetworks
|
||||
|
||||
#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_0_LOG_TEST_CASE_TO_LOGCAT_H
|
||||
@@ -20,6 +20,7 @@ cc_test {
|
||||
srcs: [
|
||||
"BasicTests.cpp",
|
||||
"TestAssertions.cpp",
|
||||
"TestMain.cpp",
|
||||
"ValidateModel.cpp",
|
||||
"ValidateRequest.cpp",
|
||||
"VtsHalNeuralnetworks.cpp",
|
||||
|
||||
@@ -26,10 +26,6 @@
|
||||
</target_preparer>
|
||||
|
||||
<test class="com.android.tradefed.testtype.GTest" >
|
||||
<!-- b/155577050, temporarily disable the failing tests.
|
||||
Must be deleted after corresponding driver issues are fixed.
|
||||
-->
|
||||
<option name="native-test-flag" value="--gtest_filter=-*Validation*:*CycleTest*:*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*" />
|
||||
<option name="native-test-device-path" value="/data/local/tmp" />
|
||||
<option name="module-name" value="VtsHalNeuralnetworksV1_1TargetTest" />
|
||||
</test>
|
||||
|
||||
25
neuralnetworks/1.1/vts/functional/TestMain.cpp
Normal file
25
neuralnetworks/1.1/vts/functional/TestMain.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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 <gtest/gtest.h>
|
||||
#include "1.0/LogTestCaseToLogcat.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
testing::UnitTest::GetInstance()->listeners().Append(
|
||||
new android::hardware::neuralnetworks::LogTestCaseToLogcat());
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -40,6 +40,7 @@ cc_test {
|
||||
"CompilationCachingTests.cpp",
|
||||
"GeneratedTestHarness.cpp",
|
||||
"TestAssertions.cpp",
|
||||
"TestMain.cpp",
|
||||
"ValidateBurst.cpp",
|
||||
"ValidateModel.cpp",
|
||||
"ValidateRequest.cpp",
|
||||
|
||||
@@ -26,10 +26,6 @@
|
||||
</target_preparer>
|
||||
|
||||
<test class="com.android.tradefed.testtype.GTest" >
|
||||
<!-- b/155577050, b/155674368, b/153876253, temporarily disable the test.
|
||||
Must be deleted after corresponding driver issues are fixed.
|
||||
-->
|
||||
<option name="native-test-flag" value="--gtest_filter=-*Validation*:*squeeze*_all*_inputs*:*strided_slice*_all*_inputs*:*transpose*_all*_inputs*:*l2_normalization_axis_corner_case*:*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*" />
|
||||
<option name="native-test-device-path" value="/data/local/tmp" />
|
||||
<option name="module-name" value="VtsHalNeuralnetworksV1_2TargetTest" />
|
||||
</test>
|
||||
|
||||
25
neuralnetworks/1.2/vts/functional/TestMain.cpp
Normal file
25
neuralnetworks/1.2/vts/functional/TestMain.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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 <gtest/gtest.h>
|
||||
#include "1.0/LogTestCaseToLogcat.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
testing::UnitTest::GetInstance()->listeners().Append(
|
||||
new android::hardware::neuralnetworks::LogTestCaseToLogcat());
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <android/hardware/neuralnetworks/1.2/IPreparedModel.h>
|
||||
#include <android/hardware/neuralnetworks/1.2/types.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <vector>
|
||||
#include "1.0/Utils.h"
|
||||
#include "1.2/Callbacks.h"
|
||||
|
||||
|
||||
@@ -5102,11 +5102,15 @@ enum OperationType : int32_t {
|
||||
* The inputs and outputs of the two referenced subgraphs must agree with the
|
||||
* signature of this operation. That is, if the operation has (3 + n) inputs
|
||||
* and m outputs, both subgraphs must have n inputs and m outputs with the same
|
||||
* types as the corresponding operation inputs and outputs.
|
||||
* types, ranks, dimensions, scales,
|
||||
* zeroPoints, and extraParams as the corresponding operation inputs and
|
||||
* outputs.
|
||||
* All of the operands mentioned must have fully specified dimensions.
|
||||
*
|
||||
* Inputs:
|
||||
* * 0: A value of type {@link OperandType::TENSOR_BOOL8} and shape [1]
|
||||
* that determines which of the two referenced subgraphs to execute.
|
||||
* The operand must have fully specified dimensions.
|
||||
* * 1: A {@link OperandType::SUBGRAPH} reference to the subgraph to be
|
||||
* executed if the condition is true.
|
||||
* * 2: A {@link OperandType::SUBGRAPH} reference to the subgraph to be
|
||||
@@ -5165,13 +5169,17 @@ enum OperationType : int32_t {
|
||||
* Inputs:
|
||||
* * 0: A {@link OperandType::SUBGRAPH} reference to the condition
|
||||
* subgraph. The subgraph must have (m + k + n) inputs with
|
||||
* the same types as the corresponding inputs of the WHILE operation
|
||||
* and exactly one output of {@link OperandType::TENSOR_BOOL8}
|
||||
* and shape [1].
|
||||
* the same types, ranks, dimensions,
|
||||
* scales, zeroPoints, and extraParams as the corresponding inputs of
|
||||
* the WHILE operation and exactly one output of
|
||||
* {@link OperandType::TENSOR_BOOL8} and shape [1].
|
||||
* All of the operands mentioned must have fully specified dimensions.
|
||||
* * 1: A {@link OperandType::SUBGRAPH} reference to the body subgraph.
|
||||
* The subgraph must have (m + k + n) inputs and (m + k) outputs with
|
||||
* the same types as the corresponding inputs and outputs of the WHILE
|
||||
* operation.
|
||||
* the same types, ranks, dimensions,
|
||||
* scales, zeroPoints, and extraParams as the corresponding inputs and
|
||||
* outputs of the WHILE operation.
|
||||
* All of the operands mentioned must have fully specified dimensions.
|
||||
* * (m inputs): Initial values for input-output operands.
|
||||
* * (k inputs): Initial values for state-only operands.
|
||||
* * (n inputs): Values for input-only operands.
|
||||
@@ -5491,7 +5499,9 @@ struct Operand {
|
||||
* If a tensor operand's dimensions are not fully specified, the
|
||||
* dimensions of the operand are deduced from the operand
|
||||
* dimensions and values of the operation for which that operand
|
||||
* is an output.
|
||||
* is an output or from the corresponding {@link OperationType::IF} or
|
||||
* {@link OperationType::WHILE} operation input operand dimensions in the
|
||||
* case of referenced subgraph input operands.
|
||||
*
|
||||
* In the following situations, a tensor operand's dimensions must
|
||||
* be fully specified:
|
||||
@@ -5499,8 +5509,8 @@ struct Operand {
|
||||
* . The operand has lifetime CONSTANT_COPY or
|
||||
* CONSTANT_REFERENCE.
|
||||
*
|
||||
* . The operand has lifetime SUBGRAPH_INPUT. Fully
|
||||
* specified dimensions must either be present in the
|
||||
* . The operand has lifetime SUBGRAPH_INPUT and belongs to the main
|
||||
* subgraph. Fully specified dimensions must either be present in the
|
||||
* Operand or they must be provided in the corresponding
|
||||
* RequestArgument.
|
||||
* EXCEPTION: If the input is optional and omitted
|
||||
|
||||
@@ -264,7 +264,9 @@ struct Operand {
|
||||
* If a tensor operand's dimensions are not fully specified, the
|
||||
* dimensions of the operand are deduced from the operand
|
||||
* dimensions and values of the operation for which that operand
|
||||
* is an output.
|
||||
* is an output or from the corresponding {@link OperationType::IF} or
|
||||
* {@link OperationType::WHILE} operation input operand dimensions in the
|
||||
* case of referenced subgraph input operands.
|
||||
*
|
||||
* In the following situations, a tensor operand's dimensions must
|
||||
* be fully specified:
|
||||
@@ -272,8 +274,8 @@ struct Operand {
|
||||
* . The operand has lifetime CONSTANT_COPY or
|
||||
* CONSTANT_REFERENCE.
|
||||
*
|
||||
* . The operand has lifetime SUBGRAPH_INPUT. Fully
|
||||
* specified dimensions must either be present in the
|
||||
* . The operand has lifetime SUBGRAPH_INPUT and belongs to the main
|
||||
* subgraph. Fully specified dimensions must either be present in the
|
||||
* Operand or they must be provided in the corresponding
|
||||
* RequestArgument.
|
||||
* EXCEPTION: If the input is optional and omitted
|
||||
|
||||
@@ -43,6 +43,7 @@ cc_test {
|
||||
"MemoryDomainTests.cpp",
|
||||
"QualityOfServiceTests.cpp",
|
||||
"TestAssertions.cpp",
|
||||
"TestMain.cpp",
|
||||
"ValidateBurst.cpp",
|
||||
"ValidateModel.cpp",
|
||||
"ValidateRequest.cpp",
|
||||
|
||||
@@ -26,10 +26,6 @@
|
||||
</target_preparer>
|
||||
|
||||
<test class="com.android.tradefed.testtype.GTest" >
|
||||
<!-- b/156691406, b/155577050, b/155674368, b/153876253, temporarily disable the test.
|
||||
Must be deleted after corresponding driver issues are fixed.
|
||||
-->
|
||||
<option name="native-test-flag" value="--gtest_filter=-*Validation*:*DynamicOutputShapeTest*:*FencedComputeTest*:*MemoryDomain*:*QuantizationCouplingTest*:*DeadlineTest*:*resize_*_v1_3*:*squeeze*_all*_inputs*:*strided_slice*_all*_inputs*:*transpose*_all*_inputs*:*l2_normalization_axis_corner_case*:*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*" />
|
||||
<option name="native-test-device-path" value="/data/local/tmp" />
|
||||
<option name="module-name" value="VtsHalNeuralnetworksV1_3TargetTest" />
|
||||
</test>
|
||||
|
||||
25
neuralnetworks/1.3/vts/functional/TestMain.cpp
Normal file
25
neuralnetworks/1.3/vts/functional/TestMain.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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 <gtest/gtest.h>
|
||||
#include "1.0/LogTestCaseToLogcat.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
testing::UnitTest::GetInstance()->listeners().Append(
|
||||
new android::hardware::neuralnetworks::LogTestCaseToLogcat());
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <android/hardware/neuralnetworks/1.3/IPreparedModel.h>
|
||||
#include <android/hardware/neuralnetworks/1.3/types.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <vector>
|
||||
#include "1.0/Utils.h"
|
||||
#include "1.3/Callbacks.h"
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <radio_hidl_hal_utils_v1_0.h>
|
||||
|
||||
using namespace ::android::hardware::radio::V1_0;
|
||||
@@ -22,6 +23,7 @@ using namespace ::android::hardware::radio::V1_0;
|
||||
* Test IRadio.setGsmBroadcastConfig() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setGsmBroadcastConfig) {
|
||||
LOG(DEBUG) << "setGsmBroadcastConfig";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
// Create GsmBroadcastSmsConfigInfo #1
|
||||
@@ -79,12 +81,14 @@ TEST_P(RadioHidlTest, setGsmBroadcastConfig) {
|
||||
RadioError::INVALID_MODEM_STATE, RadioError::INVALID_STATE},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "setGsmBroadcastConfig finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getGsmBroadcastConfig() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getGsmBroadcastConfig) {
|
||||
LOG(DEBUG) << "getGsmBroadcastConfig";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getGsmBroadcastConfig(serial);
|
||||
@@ -99,12 +103,14 @@ TEST_P(RadioHidlTest, getGsmBroadcastConfig) {
|
||||
{RadioError::NONE, RadioError::INVALID_MODEM_STATE, RadioError::INVALID_STATE},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "getGsmBroadcastConfig finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setCdmaBroadcastConfig() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setCdmaBroadcastConfig) {
|
||||
LOG(DEBUG) << "setCdmaBroadcastConfig";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
CdmaBroadcastSmsConfigInfo cbSmsConfig;
|
||||
@@ -126,12 +132,14 @@ TEST_P(RadioHidlTest, setCdmaBroadcastConfig) {
|
||||
{RadioError::NONE, RadioError::INVALID_MODEM_STATE},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "setCdmaBroadcastConfig finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getCdmaBroadcastConfig() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getCdmaBroadcastConfig) {
|
||||
LOG(DEBUG) << "getCdmaBroadcastConfig";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getCdmaBroadcastConfig(serial);
|
||||
@@ -144,12 +152,14 @@ TEST_P(RadioHidlTest, getCdmaBroadcastConfig) {
|
||||
ASSERT_TRUE(
|
||||
CheckAnyOfErrors(radioRsp->rspInfo.error, {RadioError::NONE}, CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "getCdmaBroadcastConfig finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setCdmaBroadcastActivation() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setCdmaBroadcastActivation) {
|
||||
LOG(DEBUG) << "setCdmaBroadcastActivation";
|
||||
serial = GetRandomSerialNumber();
|
||||
bool activate = false;
|
||||
|
||||
@@ -164,12 +174,14 @@ TEST_P(RadioHidlTest, setCdmaBroadcastActivation) {
|
||||
{RadioError::NONE, RadioError::INVALID_ARGUMENTS},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "setCdmaBroadcastActivation finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setGsmBroadcastActivation() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setGsmBroadcastActivation) {
|
||||
LOG(DEBUG) << "setGsmBroadcastActivation";
|
||||
serial = GetRandomSerialNumber();
|
||||
bool activate = false;
|
||||
|
||||
@@ -186,4 +198,5 @@ TEST_P(RadioHidlTest, setGsmBroadcastActivation) {
|
||||
RadioError::INVALID_STATE, RadioError::OPERATION_NOT_ALLOWED},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "setGsmBroadcastActivation finished";
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <radio_hidl_hal_utils_v1_0.h>
|
||||
|
||||
using namespace ::android::hardware::radio::V1_0;
|
||||
@@ -22,6 +23,7 @@ using namespace ::android::hardware::radio::V1_0;
|
||||
* Test IRadio.getDataRegistrationState() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getDataRegistrationState) {
|
||||
LOG(DEBUG) << "getDataRegistrationState";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getDataRegistrationState(serial);
|
||||
@@ -94,12 +96,14 @@ TEST_P(RadioHidlTest, getDataRegistrationState) {
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG(DEBUG) << "getDataRegistrationState finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setupDataCall() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setupDataCall) {
|
||||
LOG(DEBUG) << "setupDataCall";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
RadioTechnology radioTechnology = RadioTechnology::LTE;
|
||||
@@ -142,12 +146,14 @@ TEST_P(RadioHidlTest, setupDataCall) {
|
||||
RadioError::RADIO_NOT_AVAILABLE, RadioError::SIM_ABSENT},
|
||||
CHECK_OEM_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "setupDataCall finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.deactivateDataCall() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, deactivateDataCall) {
|
||||
LOG(DEBUG) << "deactivateDataCall";
|
||||
serial = GetRandomSerialNumber();
|
||||
int cid = 1;
|
||||
bool reasonRadioShutDown = false;
|
||||
@@ -164,12 +170,14 @@ TEST_P(RadioHidlTest, deactivateDataCall) {
|
||||
RadioError::SIM_ABSENT, RadioError::INVALID_CALL_ID},
|
||||
CHECK_OEM_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "deactivateDataCall finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getDataCallList() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getDataCallList) {
|
||||
LOG(DEBUG) << "getDataCallList";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getDataCallList(serial);
|
||||
@@ -183,12 +191,14 @@ TEST_P(RadioHidlTest, getDataCallList) {
|
||||
radioRsp->rspInfo.error,
|
||||
{RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::SIM_ABSENT}));
|
||||
}
|
||||
LOG(DEBUG) << "getDataCallList finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setInitialAttachApn() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setInitialAttachApn) {
|
||||
LOG(DEBUG) << "setInitialAttachApn";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
DataProfileInfo dataProfileInfo;
|
||||
@@ -226,12 +236,14 @@ TEST_P(RadioHidlTest, setInitialAttachApn) {
|
||||
RadioError::SUBSCRIPTION_NOT_AVAILABLE},
|
||||
CHECK_OEM_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "setInitialAttachApn finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setDataAllowed() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setDataAllowed) {
|
||||
LOG(DEBUG) << "setDataAllowed";
|
||||
serial = GetRandomSerialNumber();
|
||||
bool allow = true;
|
||||
|
||||
@@ -244,12 +256,14 @@ TEST_P(RadioHidlTest, setDataAllowed) {
|
||||
if (cardStatus.cardState == CardState::ABSENT) {
|
||||
EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
|
||||
}
|
||||
LOG(DEBUG) << "setDataAllowed finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setDataProfile() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setDataProfile) {
|
||||
LOG(DEBUG) << "setDataProfile";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
// Create a dataProfileInfo
|
||||
@@ -289,4 +303,5 @@ TEST_P(RadioHidlTest, setDataProfile) {
|
||||
{RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
|
||||
RadioError::SIM_ABSENT, RadioError::REQUEST_NOT_SUPPORTED}));
|
||||
}
|
||||
LOG(DEBUG) << "setDataProfile finished";
|
||||
}
|
||||
|
||||
@@ -14,22 +14,26 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <radio_hidl_hal_utils_v1_0.h>
|
||||
|
||||
/*
|
||||
* Test IRadio.getIccCardStatus() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getIccCardStatus) {
|
||||
LOG(DEBUG) << "getIccCardStatus";
|
||||
EXPECT_LE(cardStatus.applications.size(), (unsigned int)RadioConst::CARD_MAX_APPS);
|
||||
EXPECT_LT(cardStatus.gsmUmtsSubscriptionAppIndex, (int)RadioConst::CARD_MAX_APPS);
|
||||
EXPECT_LT(cardStatus.cdmaSubscriptionAppIndex, (int)RadioConst::CARD_MAX_APPS);
|
||||
EXPECT_LT(cardStatus.imsSubscriptionAppIndex, (int)RadioConst::CARD_MAX_APPS);
|
||||
LOG(DEBUG) << "getIccCardStatus finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.supplyIccPinForApp() for the response returned
|
||||
*/
|
||||
TEST_P(RadioHidlTest, supplyIccPinForApp) {
|
||||
LOG(DEBUG) << "supplyIccPinForApp";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
// Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
|
||||
@@ -49,12 +53,14 @@ TEST_P(RadioHidlTest, supplyIccPinForApp) {
|
||||
{RadioError::PASSWORD_INCORRECT, RadioError::REQUEST_NOT_SUPPORTED}));
|
||||
}
|
||||
}
|
||||
LOG(DEBUG) << "supplyIccPinForApp finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.supplyIccPukForApp() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, supplyIccPukForApp) {
|
||||
LOG(DEBUG) << "supplyIccPukForApp";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
// Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
|
||||
@@ -73,12 +79,14 @@ TEST_P(RadioHidlTest, supplyIccPukForApp) {
|
||||
RadioError::INVALID_SIM_STATE}));
|
||||
}
|
||||
}
|
||||
LOG(DEBUG) << "supplyIccPukForApp finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.supplyIccPin2ForApp() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, supplyIccPin2ForApp) {
|
||||
LOG(DEBUG) << "supplyIccPin2ForApp";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
// Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
|
||||
@@ -99,12 +107,14 @@ TEST_P(RadioHidlTest, supplyIccPin2ForApp) {
|
||||
RadioError::SIM_PUK2}));
|
||||
}
|
||||
}
|
||||
LOG(DEBUG) << "supplyIccPin2ForApp finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.supplyIccPuk2ForApp() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, supplyIccPuk2ForApp) {
|
||||
LOG(DEBUG) << "supplyIccPuk2ForApp";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
// Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
|
||||
@@ -123,12 +133,14 @@ TEST_P(RadioHidlTest, supplyIccPuk2ForApp) {
|
||||
RadioError::INVALID_SIM_STATE}));
|
||||
}
|
||||
}
|
||||
LOG(DEBUG) << "supplyIccPuk2ForApp finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.changeIccPinForApp() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, changeIccPinForApp) {
|
||||
LOG(DEBUG) << "changeIccPinForApp";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
// Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
|
||||
@@ -148,12 +160,14 @@ TEST_P(RadioHidlTest, changeIccPinForApp) {
|
||||
{RadioError::PASSWORD_INCORRECT, RadioError::REQUEST_NOT_SUPPORTED}));
|
||||
}
|
||||
}
|
||||
LOG(DEBUG) << "changeIccPinForApp finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.changeIccPin2ForApp() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, changeIccPin2ForApp) {
|
||||
LOG(DEBUG) << "changeIccPin2ForApp";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
// Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
|
||||
@@ -174,6 +188,7 @@ TEST_P(RadioHidlTest, changeIccPin2ForApp) {
|
||||
RadioError::SIM_PUK2}));
|
||||
}
|
||||
}
|
||||
LOG(DEBUG) << "changeIccPin2ForApp finished";
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -182,6 +197,7 @@ TEST_P(RadioHidlTest, changeIccPin2ForApp) {
|
||||
* Test IRadio.getImsiForApp() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, DISABLED_getImsiForApp) {
|
||||
LOG(DEBUG) << "DISABLED_getImsiForApp";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
// Check success returned while getting imsi for 3GPP and 3GPP2 apps only
|
||||
@@ -205,12 +221,14 @@ TEST_P(RadioHidlTest, DISABLED_getImsiForApp) {
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG(DEBUG) << "DISABLED_getImsiForApp finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.iccIOForApp() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, iccIOForApp) {
|
||||
LOG(DEBUG) << "iccIOForApp";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
|
||||
@@ -230,12 +248,14 @@ TEST_P(RadioHidlTest, iccIOForApp) {
|
||||
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
|
||||
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
|
||||
}
|
||||
LOG(DEBUG) << "iccIOForApp finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.iccTransmitApduBasicChannel() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, iccTransmitApduBasicChannel) {
|
||||
LOG(DEBUG) << "iccTransmitApduBasicChannel";
|
||||
serial = GetRandomSerialNumber();
|
||||
SimApdu msg;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
@@ -247,12 +267,14 @@ TEST_P(RadioHidlTest, iccTransmitApduBasicChannel) {
|
||||
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
|
||||
|
||||
// TODO(sanketpadawe): Add test for error code
|
||||
LOG(DEBUG) << "iccTransmitApduBasicChannel finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.iccOpenLogicalChannel() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, iccOpenLogicalChannel) {
|
||||
LOG(DEBUG) << "iccOpenLogicalChannel";
|
||||
serial = GetRandomSerialNumber();
|
||||
int p2 = 0x04;
|
||||
// Specified in ISO 7816-4 clause 7.1.1 0x04 means that FCP template is requested.
|
||||
@@ -262,12 +284,14 @@ TEST_P(RadioHidlTest, iccOpenLogicalChannel) {
|
||||
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
|
||||
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
|
||||
}
|
||||
LOG(DEBUG) << "iccOpenLogicalChannel finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.iccCloseLogicalChannel() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, iccCloseLogicalChannel) {
|
||||
LOG(DEBUG) << "iccCloseLogicalChannel";
|
||||
serial = GetRandomSerialNumber();
|
||||
// Try closing invalid channel and check INVALID_ARGUMENTS returned as error
|
||||
radio->iccCloseLogicalChannel(serial, 0);
|
||||
@@ -276,12 +300,14 @@ TEST_P(RadioHidlTest, iccCloseLogicalChannel) {
|
||||
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
|
||||
|
||||
EXPECT_EQ(RadioError::INVALID_ARGUMENTS, radioRsp->rspInfo.error);
|
||||
LOG(DEBUG) << "iccCloseLogicalChannel finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.iccTransmitApduLogicalChannel() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, iccTransmitApduLogicalChannel) {
|
||||
LOG(DEBUG) << "iccTransmitApduLogicalChannel";
|
||||
serial = GetRandomSerialNumber();
|
||||
SimApdu msg;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
@@ -293,12 +319,14 @@ TEST_P(RadioHidlTest, iccTransmitApduLogicalChannel) {
|
||||
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
|
||||
|
||||
// TODO(sanketpadawe): Add test for error code
|
||||
LOG(DEBUG) << "iccTransmitApduLogicalChannel finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.requestIccSimAuthentication() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, requestIccSimAuthentication) {
|
||||
LOG(DEBUG) << "requestIccSimAuthentication";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
// Pass wrong challenge string and check RadioError::INVALID_ARGUMENTS
|
||||
@@ -312,12 +340,14 @@ TEST_P(RadioHidlTest, requestIccSimAuthentication) {
|
||||
ASSERT_TRUE(CheckAnyOfErrors(radioRsp->rspInfo.error, {RadioError::INVALID_ARGUMENTS,
|
||||
RadioError::REQUEST_NOT_SUPPORTED}));
|
||||
}
|
||||
LOG(DEBUG) << "requestIccSimAuthentication finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.supplyNetworkDepersonalization() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, supplyNetworkDepersonalization) {
|
||||
LOG(DEBUG) << "supplyNetworkDepersonalization";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->supplyNetworkDepersonalization(serial, hidl_string("test"));
|
||||
@@ -332,4 +362,5 @@ TEST_P(RadioHidlTest, supplyNetworkDepersonalization) {
|
||||
RadioError::INVALID_SIM_STATE, RadioError::MODEM_ERR, RadioError::NO_MEMORY,
|
||||
RadioError::PASSWORD_INCORRECT, RadioError::SIM_ABSENT, RadioError::SYSTEM_ERR}));
|
||||
}
|
||||
LOG(DEBUG) << "supplyNetworkDepersonalization finished";
|
||||
}
|
||||
|
||||
@@ -14,12 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <radio_hidl_hal_utils_v1_0.h>
|
||||
|
||||
/*
|
||||
* Test IRadio.getSignalStrength() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getSignalStrength) {
|
||||
LOG(DEBUG) << "getSignalStrength";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getSignalStrength(serial);
|
||||
@@ -30,12 +32,14 @@ TEST_P(RadioHidlTest, getSignalStrength) {
|
||||
if (cardStatus.cardState == CardState::ABSENT) {
|
||||
EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
|
||||
}
|
||||
LOG(DEBUG) << "getSignalStrength finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getVoiceRegistrationState() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getVoiceRegistrationState) {
|
||||
LOG(DEBUG) << "getVoiceRegistrationState";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getVoiceRegistrationState(serial);
|
||||
@@ -46,12 +50,14 @@ TEST_P(RadioHidlTest, getVoiceRegistrationState) {
|
||||
if (cardStatus.cardState == CardState::ABSENT) {
|
||||
EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
|
||||
}
|
||||
LOG(DEBUG) << "getVoiceRegistrationState finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getOperator() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getOperator) {
|
||||
LOG(DEBUG) << "getOperator";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getOperator(serial);
|
||||
@@ -62,12 +68,14 @@ TEST_P(RadioHidlTest, getOperator) {
|
||||
if (cardStatus.cardState == CardState::ABSENT) {
|
||||
EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
|
||||
}
|
||||
LOG(DEBUG) << "getOperator finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setRadioPower() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setRadioPower) {
|
||||
LOG(DEBUG) << "setRadioPower";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->setRadioPower(serial, 1);
|
||||
@@ -78,12 +86,14 @@ TEST_P(RadioHidlTest, setRadioPower) {
|
||||
if (cardStatus.cardState == CardState::ABSENT) {
|
||||
EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
|
||||
}
|
||||
LOG(DEBUG) << "setRadioPower finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getNetworkSelectionMode() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getNetworkSelectionMode) {
|
||||
LOG(DEBUG) << "getNetworkSelectionMode";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getNetworkSelectionMode(serial);
|
||||
@@ -94,12 +104,14 @@ TEST_P(RadioHidlTest, getNetworkSelectionMode) {
|
||||
if (cardStatus.cardState == CardState::ABSENT) {
|
||||
EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
|
||||
}
|
||||
LOG(DEBUG) << "getNetworkSelectionMode finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setNetworkSelectionModeAutomatic() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setNetworkSelectionModeAutomatic) {
|
||||
LOG(DEBUG) << "setNetworkSelectionModeAutomatic";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->setNetworkSelectionModeAutomatic(serial);
|
||||
@@ -113,12 +125,14 @@ TEST_P(RadioHidlTest, setNetworkSelectionModeAutomatic) {
|
||||
{RadioError::NONE, RadioError::ILLEGAL_SIM_OR_ME, RadioError::OPERATION_NOT_ALLOWED},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "setNetworkSelectionModeAutomatic finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setNetworkSelectionModeManual() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setNetworkSelectionModeManual) {
|
||||
LOG(DEBUG) << "setNetworkSelectionModeManual";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->setNetworkSelectionModeManual(serial, "123456");
|
||||
@@ -132,12 +146,14 @@ TEST_P(RadioHidlTest, setNetworkSelectionModeManual) {
|
||||
RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "setNetworkSelectionModeManual finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getAvailableNetworks() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getAvailableNetworks) {
|
||||
LOG(DEBUG) << "getAvailableNetworks";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getAvailableNetworks(serial);
|
||||
@@ -153,12 +169,14 @@ TEST_P(RadioHidlTest, getAvailableNetworks) {
|
||||
RadioError::MODEM_ERR, RadioError::OPERATION_NOT_ALLOWED},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "getAvailableNetworks finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getBasebandVersion() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getBasebandVersion) {
|
||||
LOG(DEBUG) << "getBasebandVersion";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getBasebandVersion(serial);
|
||||
@@ -169,12 +187,14 @@ TEST_P(RadioHidlTest, getBasebandVersion) {
|
||||
if (cardStatus.cardState == CardState::ABSENT) {
|
||||
EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
|
||||
}
|
||||
LOG(DEBUG) << "getBasebandVersion finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setBandMode() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setBandMode) {
|
||||
LOG(DEBUG) << "setBandMode";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->setBandMode(serial, RadioBandMode::BAND_MODE_USA);
|
||||
@@ -186,12 +206,14 @@ TEST_P(RadioHidlTest, setBandMode) {
|
||||
ASSERT_TRUE(
|
||||
CheckAnyOfErrors(radioRsp->rspInfo.error, {RadioError::NONE}, CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "setBandMode finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getAvailableBandModes() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getAvailableBandModes) {
|
||||
LOG(DEBUG) << "getAvailableBandModes";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getAvailableBandModes(serial);
|
||||
@@ -202,12 +224,14 @@ TEST_P(RadioHidlTest, getAvailableBandModes) {
|
||||
if (cardStatus.cardState == CardState::ABSENT) {
|
||||
EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
|
||||
}
|
||||
LOG(DEBUG) << "getAvailableBandModes finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setPreferredNetworkType() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setPreferredNetworkType) {
|
||||
LOG(DEBUG) << "setPreferredNetworkType";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->setPreferredNetworkType(serial, PreferredNetworkType::GSM_ONLY);
|
||||
@@ -219,12 +243,14 @@ TEST_P(RadioHidlTest, setPreferredNetworkType) {
|
||||
ASSERT_TRUE(
|
||||
CheckAnyOfErrors(radioRsp->rspInfo.error, {RadioError::NONE}, CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "setPreferredNetworkType finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getPreferredNetworkType() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getPreferredNetworkType) {
|
||||
LOG(DEBUG) << "getPreferredNetworkType";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getPreferredNetworkType(serial);
|
||||
@@ -235,12 +261,14 @@ TEST_P(RadioHidlTest, getPreferredNetworkType) {
|
||||
if (cardStatus.cardState == CardState::ABSENT) {
|
||||
EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
|
||||
}
|
||||
LOG(DEBUG) << "getPreferredNetworkType finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getNeighboringCids() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getNeighboringCids) {
|
||||
LOG(DEBUG) << "getNeighboringCids";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getNeighboringCids(serial);
|
||||
@@ -253,12 +281,14 @@ TEST_P(RadioHidlTest, getNeighboringCids) {
|
||||
{RadioError::NONE, RadioError::SIM_ABSENT},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "getNeighboringCids finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setLocationUpdates() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setLocationUpdates) {
|
||||
LOG(DEBUG) << "setLocationUpdates";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->setLocationUpdates(serial, true);
|
||||
@@ -270,12 +300,14 @@ TEST_P(RadioHidlTest, setLocationUpdates) {
|
||||
ASSERT_TRUE(
|
||||
CheckAnyOfErrors(radioRsp->rspInfo.error, {RadioError::NONE, RadioError::SIM_ABSENT}));
|
||||
}
|
||||
LOG(DEBUG) << "setLocationUpdates finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setCdmaRoamingPreference() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setCdmaRoamingPreference) {
|
||||
LOG(DEBUG) << "setCdmaRoamingPreference";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->setCdmaRoamingPreference(serial, CdmaRoamingType::HOME_NETWORK);
|
||||
@@ -288,12 +320,14 @@ TEST_P(RadioHidlTest, setCdmaRoamingPreference) {
|
||||
radioRsp->rspInfo.error,
|
||||
{RadioError::NONE, RadioError::SIM_ABSENT, RadioError::REQUEST_NOT_SUPPORTED}));
|
||||
}
|
||||
LOG(DEBUG) << "setCdmaRoamingPreference finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getCdmaRoamingPreference() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getCdmaRoamingPreference) {
|
||||
LOG(DEBUG) << "getCdmaRoamingPreference";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getCdmaRoamingPreference(serial);
|
||||
@@ -307,12 +341,14 @@ TEST_P(RadioHidlTest, getCdmaRoamingPreference) {
|
||||
{RadioError::NONE, RadioError::SIM_ABSENT, RadioError::MODEM_ERR},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "getCdmaRoamingPreference finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getTTYMode() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getTTYMode) {
|
||||
LOG(DEBUG) << "getTTYMode";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getTTYMode(serial);
|
||||
@@ -323,12 +359,14 @@ TEST_P(RadioHidlTest, getTTYMode) {
|
||||
if (cardStatus.cardState == CardState::ABSENT) {
|
||||
EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
|
||||
}
|
||||
LOG(DEBUG) << "getTTYMode finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setTTYMode() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setTTYMode) {
|
||||
LOG(DEBUG) << "setTTYMode";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->setTTYMode(serial, TtyMode::OFF);
|
||||
@@ -339,12 +377,14 @@ TEST_P(RadioHidlTest, setTTYMode) {
|
||||
if (cardStatus.cardState == CardState::ABSENT) {
|
||||
EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
|
||||
}
|
||||
LOG(DEBUG) << "setTTYMode finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setPreferredVoicePrivacy() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setPreferredVoicePrivacy) {
|
||||
LOG(DEBUG) << "setPreferredVoicePrivacy";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->setPreferredVoicePrivacy(serial, true);
|
||||
@@ -356,12 +396,14 @@ TEST_P(RadioHidlTest, setPreferredVoicePrivacy) {
|
||||
ASSERT_TRUE(CheckAnyOfErrors(radioRsp->rspInfo.error,
|
||||
{RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
|
||||
}
|
||||
LOG(DEBUG) << "setPreferredVoicePrivacy finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getPreferredVoicePrivacy() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getPreferredVoicePrivacy) {
|
||||
LOG(DEBUG) << "getPreferredVoicePrivacy";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getPreferredVoicePrivacy(serial);
|
||||
@@ -373,12 +415,14 @@ TEST_P(RadioHidlTest, getPreferredVoicePrivacy) {
|
||||
ASSERT_TRUE(CheckAnyOfErrors(radioRsp->rspInfo.error,
|
||||
{RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
|
||||
}
|
||||
LOG(DEBUG) << "getPreferredVoicePrivacy finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getCDMASubscription() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getCDMASubscription) {
|
||||
LOG(DEBUG) << "getCDMASubscription";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getCDMASubscription(serial);
|
||||
@@ -391,12 +435,14 @@ TEST_P(RadioHidlTest, getCDMASubscription) {
|
||||
radioRsp->rspInfo.error,
|
||||
{RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_ABSENT}));
|
||||
}
|
||||
LOG(DEBUG) << "getCDMASubscription finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getDeviceIdentity() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getDeviceIdentity) {
|
||||
LOG(DEBUG) << "getDeviceIdentity";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getDeviceIdentity(serial);
|
||||
@@ -408,12 +454,14 @@ TEST_P(RadioHidlTest, getDeviceIdentity) {
|
||||
ASSERT_TRUE(CheckAnyOfErrors(radioRsp->rspInfo.error,
|
||||
{RadioError::NONE, RadioError::EMPTY_RECORD}));
|
||||
}
|
||||
LOG(DEBUG) << "getDeviceIdentity finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.exitEmergencyCallbackMode() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, exitEmergencyCallbackMode) {
|
||||
LOG(DEBUG) << "exitEmergencyCallbackMode";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->exitEmergencyCallbackMode(serial);
|
||||
@@ -426,12 +474,14 @@ TEST_P(RadioHidlTest, exitEmergencyCallbackMode) {
|
||||
radioRsp->rspInfo.error,
|
||||
{RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_ABSENT}));
|
||||
}
|
||||
LOG(DEBUG) << "exitEmergencyCallbackMode finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getCdmaSubscriptionSource() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getCdmaSubscriptionSource) {
|
||||
LOG(DEBUG) << "getCdmaSubscriptionSource";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getCdmaSubscriptionSource(serial);
|
||||
@@ -444,12 +494,14 @@ TEST_P(RadioHidlTest, getCdmaSubscriptionSource) {
|
||||
radioRsp->rspInfo.error,
|
||||
{RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_ABSENT}));
|
||||
}
|
||||
LOG(DEBUG) << "getCdmaSubscriptionSource finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setCdmaSubscriptionSource() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setCdmaSubscriptionSource) {
|
||||
LOG(DEBUG) << "setCdmaSubscriptionSource";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->setCdmaSubscriptionSource(serial, CdmaSubscriptionSource::RUIM_SIM);
|
||||
@@ -463,12 +515,14 @@ TEST_P(RadioHidlTest, setCdmaSubscriptionSource) {
|
||||
{RadioError::NONE, RadioError::SIM_ABSENT, RadioError::SUBSCRIPTION_NOT_AVAILABLE},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "setCdmaSubscriptionSource finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getVoiceRadioTechnology() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getVoiceRadioTechnology) {
|
||||
LOG(DEBUG) << "getVoiceRadioTechnology";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getVoiceRadioTechnology(serial);
|
||||
@@ -479,12 +533,14 @@ TEST_P(RadioHidlTest, getVoiceRadioTechnology) {
|
||||
if (cardStatus.cardState == CardState::ABSENT) {
|
||||
EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
|
||||
}
|
||||
LOG(DEBUG) << "getVoiceRadioTechnology finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getCellInfoList() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getCellInfoList) {
|
||||
LOG(DEBUG) << "getCellInfoList";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getCellInfoList(serial);
|
||||
@@ -497,12 +553,14 @@ TEST_P(RadioHidlTest, getCellInfoList) {
|
||||
{RadioError::NONE, RadioError::NO_NETWORK_FOUND},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "getCellInfoList finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setCellInfoListRate() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setCellInfoListRate) {
|
||||
LOG(DEBUG) << "setCellInfoListRate";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
// TODO(sanketpadawe): RIL crashes with value of rate = 10
|
||||
@@ -515,12 +573,14 @@ TEST_P(RadioHidlTest, setCellInfoListRate) {
|
||||
ASSERT_TRUE(CheckAnyOfErrors(radioRsp->rspInfo.error,
|
||||
{RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
|
||||
}
|
||||
LOG(DEBUG) << "setCellInfoListRate finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.nvReadItem() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, nvReadItem) {
|
||||
LOG(DEBUG) << "nvReadItem";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->nvReadItem(serial, NvItem::LTE_BAND_ENABLE_25);
|
||||
@@ -532,12 +592,14 @@ TEST_P(RadioHidlTest, nvReadItem) {
|
||||
ASSERT_TRUE(
|
||||
CheckAnyOfErrors(radioRsp->rspInfo.error, {RadioError::NONE}, CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "nvReadItem finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.nvWriteItem() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, nvWriteItem) {
|
||||
LOG(DEBUG) << "nvWriteItem";
|
||||
serial = GetRandomSerialNumber();
|
||||
NvWriteItem item;
|
||||
memset(&item, 0, sizeof(item));
|
||||
@@ -552,12 +614,14 @@ TEST_P(RadioHidlTest, nvWriteItem) {
|
||||
ASSERT_TRUE(
|
||||
CheckAnyOfErrors(radioRsp->rspInfo.error, {RadioError::NONE}, CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "nvWriteItem finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.nvWriteCdmaPrl() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, nvWriteCdmaPrl) {
|
||||
LOG(DEBUG) << "nvWriteCdmaPrl";
|
||||
serial = GetRandomSerialNumber();
|
||||
std::vector<uint8_t> prl = {1, 2, 3, 4, 5};
|
||||
|
||||
@@ -570,12 +634,14 @@ TEST_P(RadioHidlTest, nvWriteCdmaPrl) {
|
||||
ASSERT_TRUE(
|
||||
CheckAnyOfErrors(radioRsp->rspInfo.error, {RadioError::NONE}, CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "nvWriteCdmaPrl finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.nvResetConfig() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, nvResetConfig) {
|
||||
LOG(DEBUG) << "nvResetConfig";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->nvResetConfig(serial, ResetNvType::FACTORY_RESET);
|
||||
@@ -587,12 +653,14 @@ TEST_P(RadioHidlTest, nvResetConfig) {
|
||||
ASSERT_TRUE(CheckAnyOfErrors(radioRsp->rspInfo.error,
|
||||
{RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
|
||||
}
|
||||
LOG(DEBUG) << "nvResetConfig finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setUiccSubscription() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setUiccSubscription) {
|
||||
LOG(DEBUG) << "setUiccSubscription";
|
||||
serial = GetRandomSerialNumber();
|
||||
SelectUiccSub item;
|
||||
memset(&item, 0, sizeof(item));
|
||||
@@ -609,12 +677,14 @@ TEST_P(RadioHidlTest, setUiccSubscription) {
|
||||
RadioError::MODEM_ERR, RadioError::SUBSCRIPTION_NOT_SUPPORTED},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "setUiccSubscription finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getHardwareConfig() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getHardwareConfig) {
|
||||
LOG(DEBUG) << "getHardwareConfig";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getHardwareConfig(serial);
|
||||
@@ -626,6 +696,7 @@ TEST_P(RadioHidlTest, getHardwareConfig) {
|
||||
ASSERT_TRUE(
|
||||
CheckAnyOfErrors(radioRsp->rspInfo.error, {RadioError::NONE}, CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "getHardwareConfig finished";
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -651,6 +722,7 @@ TEST_P(RadioHidlTest, DISABLED_requestShutdown) {
|
||||
* Test IRadio.getRadioCapability() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getRadioCapability) {
|
||||
LOG(DEBUG) << "getRadioCapability";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getRadioCapability(serial);
|
||||
@@ -661,12 +733,14 @@ TEST_P(RadioHidlTest, getRadioCapability) {
|
||||
if (cardStatus.cardState == CardState::ABSENT) {
|
||||
EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
|
||||
}
|
||||
LOG(DEBUG) << "getRadioCapability finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setRadioCapability() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setRadioCapability) {
|
||||
LOG(DEBUG) << "setRadioCapability";
|
||||
serial = GetRandomSerialNumber();
|
||||
RadioCapability rc;
|
||||
memset(&rc, 0, sizeof(rc));
|
||||
@@ -682,12 +756,14 @@ TEST_P(RadioHidlTest, setRadioCapability) {
|
||||
{RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "setRadioCapability finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.startLceService() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, startLceService) {
|
||||
LOG(DEBUG) << "startLceService";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->startLceService(serial, 5, true);
|
||||
@@ -701,12 +777,14 @@ TEST_P(RadioHidlTest, startLceService) {
|
||||
{RadioError::INTERNAL_ERR, RadioError::LCE_NOT_SUPPORTED,
|
||||
RadioError::RADIO_NOT_AVAILABLE, RadioError::SIM_ABSENT, RadioError::NONE}));
|
||||
}
|
||||
LOG(DEBUG) << "startLceService finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.stopLceService() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, stopLceService) {
|
||||
LOG(DEBUG) << "stopLceService";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->stopLceService(serial);
|
||||
@@ -719,12 +797,14 @@ TEST_P(RadioHidlTest, stopLceService) {
|
||||
{RadioError::NONE, RadioError::LCE_NOT_SUPPORTED,
|
||||
RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_ABSENT}));
|
||||
}
|
||||
LOG(DEBUG) << "stopLceService finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.pullLceData() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, pullLceData) {
|
||||
LOG(DEBUG) << "pullLceData";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->pullLceData(serial);
|
||||
@@ -738,12 +818,14 @@ TEST_P(RadioHidlTest, pullLceData) {
|
||||
RadioError::RADIO_NOT_AVAILABLE, RadioError::SIM_ABSENT},
|
||||
CHECK_OEM_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "pullLceData finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getModemActivityInfo() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getModemActivityInfo) {
|
||||
LOG(DEBUG) << "getModemActivityInfo";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getModemActivityInfo(serial);
|
||||
@@ -755,6 +837,7 @@ TEST_P(RadioHidlTest, getModemActivityInfo) {
|
||||
ASSERT_TRUE(CheckAnyOfErrors(radioRsp->rspInfo.error,
|
||||
{RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
|
||||
}
|
||||
LOG(DEBUG) << "getModemActivityInfo finished";
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -840,6 +923,7 @@ TEST_P(RadioHidlTest, DISABLED_setAllowedCarriers) {
|
||||
* Test IRadio.getAllowedCarriers() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getAllowedCarriers) {
|
||||
LOG(DEBUG) << "getAllowedCarriers";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getAllowedCarriers(serial);
|
||||
@@ -851,12 +935,14 @@ TEST_P(RadioHidlTest, getAllowedCarriers) {
|
||||
ASSERT_TRUE(CheckAnyOfErrors(radioRsp->rspInfo.error,
|
||||
{RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
|
||||
}
|
||||
LOG(DEBUG) << "getAllowedCarriers finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.sendDeviceState() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, sendDeviceState) {
|
||||
LOG(DEBUG) << "sendDeviceState";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->sendDeviceState(serial, DeviceStateType::POWER_SAVE_MODE, true);
|
||||
@@ -870,12 +956,14 @@ TEST_P(RadioHidlTest, sendDeviceState) {
|
||||
ASSERT_TRUE(CheckAnyOfErrors(radioRsp->rspInfo.error,
|
||||
{RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
|
||||
}
|
||||
LOG(DEBUG) << "sendDeviceState finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setIndicationFilter() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setIndicationFilter) {
|
||||
LOG(DEBUG) << "setIndicationFilter";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->setIndicationFilter(serial, 1);
|
||||
@@ -889,12 +977,14 @@ TEST_P(RadioHidlTest, setIndicationFilter) {
|
||||
ASSERT_TRUE(CheckAnyOfErrors(radioRsp->rspInfo.error,
|
||||
{RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
|
||||
}
|
||||
LOG(DEBUG) << "setIndicationFilter finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setSimCardPower() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setSimCardPower) {
|
||||
LOG(DEBUG) << "setSimCardPower";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->setSimCardPower(serial, true);
|
||||
@@ -906,4 +996,5 @@ TEST_P(RadioHidlTest, setSimCardPower) {
|
||||
ASSERT_TRUE(CheckAnyOfErrors(radioRsp->rspInfo.error,
|
||||
{RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
|
||||
}
|
||||
LOG(DEBUG) << "setSimCardPower finished";
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <radio_hidl_hal_utils_v1_0.h>
|
||||
|
||||
using namespace ::android::hardware::radio::V1_0;
|
||||
@@ -22,6 +23,7 @@ using namespace ::android::hardware::radio::V1_0;
|
||||
* Test IRadio.sendSms() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, sendSms) {
|
||||
LOG(DEBUG) << "sendSms";
|
||||
serial = GetRandomSerialNumber();
|
||||
GsmSmsMessage msg;
|
||||
msg.smscPdu = "";
|
||||
@@ -40,12 +42,14 @@ TEST_P(RadioHidlTest, sendSms) {
|
||||
CHECK_GENERAL_ERROR));
|
||||
EXPECT_EQ(0, radioRsp->sendSmsResult.errorCode);
|
||||
}
|
||||
LOG(DEBUG) << "sendSms finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.sendSMSExpectMore() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, sendSMSExpectMore) {
|
||||
LOG(DEBUG) << "sendSMSExpectMore";
|
||||
serial = GetRandomSerialNumber();
|
||||
GsmSmsMessage msg;
|
||||
msg.smscPdu = "";
|
||||
@@ -66,12 +70,14 @@ TEST_P(RadioHidlTest, sendSMSExpectMore) {
|
||||
{RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::SIM_ABSENT},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "sendSMSExpectMore finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.acknowledgeLastIncomingGsmSms() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, acknowledgeLastIncomingGsmSms) {
|
||||
LOG(DEBUG) << "acknowledgeLastIncomingGsmSms";
|
||||
serial = GetRandomSerialNumber();
|
||||
bool success = true;
|
||||
|
||||
@@ -87,12 +93,14 @@ TEST_P(RadioHidlTest, acknowledgeLastIncomingGsmSms) {
|
||||
{RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "acknowledgeLastIncomingGsmSms finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.acknowledgeIncomingGsmSmsWithPdu() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, acknowledgeIncomingGsmSmsWithPdu) {
|
||||
LOG(DEBUG) << "acknowledgeIncomingGsmSmsWithPdu";
|
||||
serial = GetRandomSerialNumber();
|
||||
bool success = true;
|
||||
std::string ackPdu = "";
|
||||
@@ -106,12 +114,14 @@ TEST_P(RadioHidlTest, acknowledgeIncomingGsmSmsWithPdu) {
|
||||
if (cardStatus.cardState == CardState::ABSENT) {
|
||||
// TODO(shuoq): Will add error check when we know the expected error from QC
|
||||
}
|
||||
LOG(DEBUG) << "acknowledgeIncomingGsmSmsWithPdu finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.sendCdmaSms() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, sendCdmaSms) {
|
||||
LOG(DEBUG) << "sendCdmaSms";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
// Create a CdmaSmsAddress
|
||||
@@ -150,12 +160,14 @@ TEST_P(RadioHidlTest, sendCdmaSms) {
|
||||
{RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::SIM_ABSENT},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "sendCdmaSms finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.acknowledgeLastIncomingCdmaSms() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, acknowledgeLastIncomingCdmaSms) {
|
||||
LOG(DEBUG) << "acknowledgeLastIncomingCdmaSms";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
// Create a CdmaSmsAck
|
||||
@@ -174,12 +186,14 @@ TEST_P(RadioHidlTest, acknowledgeLastIncomingCdmaSms) {
|
||||
{RadioError::INVALID_ARGUMENTS, RadioError::NO_SMS_TO_ACK},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "acknowledgeLastIncomingCdmaSms finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.sendImsSms() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, sendImsSms) {
|
||||
LOG(DEBUG) << "sendImsSms";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
// Create a CdmaSmsAddress
|
||||
@@ -224,12 +238,14 @@ TEST_P(RadioHidlTest, sendImsSms) {
|
||||
ASSERT_TRUE(CheckAnyOfErrors(radioRsp->rspInfo.error, {RadioError::INVALID_ARGUMENTS},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "sendImsSms finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getSmscAddress() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getSmscAddress) {
|
||||
LOG(DEBUG) << "getSmscAddress";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getSmscAddress(serial);
|
||||
@@ -244,12 +260,14 @@ TEST_P(RadioHidlTest, getSmscAddress) {
|
||||
{RadioError::INVALID_MODEM_STATE, RadioError::INVALID_STATE, RadioError::SIM_ABSENT},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "getSmscAddress finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setSmscAddress() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setSmscAddress) {
|
||||
LOG(DEBUG) << "setSmscAddress";
|
||||
serial = GetRandomSerialNumber();
|
||||
hidl_string address = hidl_string("smscAddress");
|
||||
|
||||
@@ -265,12 +283,14 @@ TEST_P(RadioHidlTest, setSmscAddress) {
|
||||
{RadioError::INVALID_ARGUMENTS, RadioError::INVALID_SMS_FORMAT, RadioError::SIM_ABSENT},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "setSmscAddress finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.writeSmsToSim() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, writeSmsToSim) {
|
||||
LOG(DEBUG) << "writeSmsToSim";
|
||||
serial = GetRandomSerialNumber();
|
||||
SmsWriteArgs smsWriteArgs;
|
||||
smsWriteArgs.status = SmsWriteArgsStatus::REC_UNREAD;
|
||||
@@ -291,12 +311,14 @@ TEST_P(RadioHidlTest, writeSmsToSim) {
|
||||
RadioError::NO_RESOURCES, RadioError::SIM_ABSENT},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "writeSmsToSim finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.deleteSmsOnSim() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, deleteSmsOnSim) {
|
||||
LOG(DEBUG) << "deleteSmsOnSim";
|
||||
serial = GetRandomSerialNumber();
|
||||
int index = 1;
|
||||
|
||||
@@ -314,12 +336,14 @@ TEST_P(RadioHidlTest, deleteSmsOnSim) {
|
||||
RadioError::SIM_ABSENT},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "deleteSmsOnSim finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.writeSmsToRuim() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, writeSmsToRuim) {
|
||||
LOG(DEBUG) << "writeSmsToRuim";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
// Create a CdmaSmsAddress
|
||||
@@ -365,12 +389,14 @@ TEST_P(RadioHidlTest, writeSmsToRuim) {
|
||||
RadioError::NO_SUCH_ENTRY, RadioError::SIM_ABSENT},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "writeSmsToRuim finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.deleteSmsOnRuim() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, deleteSmsOnRuim) {
|
||||
LOG(DEBUG) << "deleteSmsOnRuim";
|
||||
serial = GetRandomSerialNumber();
|
||||
int index = 1;
|
||||
|
||||
@@ -416,12 +442,14 @@ TEST_P(RadioHidlTest, deleteSmsOnRuim) {
|
||||
RadioError::MODEM_ERR, RadioError::NO_SUCH_ENTRY, RadioError::SIM_ABSENT},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "deleteSmsOnRuim finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.reportSmsMemoryStatus() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, reportSmsMemoryStatus) {
|
||||
LOG(DEBUG) << "reportSmsMemoryStatus";
|
||||
serial = GetRandomSerialNumber();
|
||||
bool available = true;
|
||||
|
||||
@@ -437,4 +465,5 @@ TEST_P(RadioHidlTest, reportSmsMemoryStatus) {
|
||||
RadioError::MODEM_ERR, RadioError::SIM_ABSENT},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "reportSmsMemoryStatus finished";
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <radio_hidl_hal_utils_v1_0.h>
|
||||
|
||||
using namespace ::android::hardware::radio::V1_0;
|
||||
@@ -22,6 +23,7 @@ using namespace ::android::hardware::radio::V1_0;
|
||||
* Test IRadio.sendEnvelope() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, sendEnvelope) {
|
||||
LOG(DEBUG) << "sendEnvelope";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
// Test with sending empty string
|
||||
@@ -39,12 +41,14 @@ TEST_P(RadioHidlTest, sendEnvelope) {
|
||||
RadioError::MODEM_ERR, RadioError::SIM_ABSENT},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "sendEnvelope finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.sendTerminalResponseToSim() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, sendTerminalResponseToSim) {
|
||||
LOG(DEBUG) << "sendTerminalResponseToSim";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
// Test with sending empty string
|
||||
@@ -62,12 +66,14 @@ TEST_P(RadioHidlTest, sendTerminalResponseToSim) {
|
||||
{RadioError::NONE, RadioError::INVALID_ARGUMENTS, RadioError::SIM_ABSENT},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "sendTerminalResponseToSim finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.handleStkCallSetupRequestFromSim() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, handleStkCallSetupRequestFromSim) {
|
||||
LOG(DEBUG) << "handleStkCallSetupRequestFromSim";
|
||||
serial = GetRandomSerialNumber();
|
||||
bool accept = false;
|
||||
|
||||
@@ -83,12 +89,14 @@ TEST_P(RadioHidlTest, handleStkCallSetupRequestFromSim) {
|
||||
RadioError::MODEM_ERR, RadioError::SIM_ABSENT},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "handleStkCallSetupRequestFromSim finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.reportStkServiceIsRunning() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, reportStkServiceIsRunning) {
|
||||
LOG(DEBUG) << "reportStkServiceIsRunning";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->reportStkServiceIsRunning(serial);
|
||||
@@ -101,6 +109,7 @@ TEST_P(RadioHidlTest, reportStkServiceIsRunning) {
|
||||
ASSERT_TRUE(
|
||||
CheckAnyOfErrors(radioRsp->rspInfo.error, {RadioError::NONE}, CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "reportStkServiceIsRunning finished";
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -108,6 +117,7 @@ TEST_P(RadioHidlTest, reportStkServiceIsRunning) {
|
||||
* string.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, sendEnvelopeWithStatus) {
|
||||
LOG(DEBUG) << "sendEnvelopeWithStatus";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
// Test with sending empty string
|
||||
@@ -125,4 +135,5 @@ TEST_P(RadioHidlTest, sendEnvelopeWithStatus) {
|
||||
{RadioError::INVALID_ARGUMENTS, RadioError::MODEM_ERR, RadioError::SIM_ABSENT},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "sendEnvelopeWithStatus finished";
|
||||
}
|
||||
|
||||
@@ -14,11 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <radio_hidl_hal_utils_v1_0.h>
|
||||
|
||||
void RadioHidlTest::SetUp() {
|
||||
radio = IRadio::getService(GetParam());
|
||||
if (radio == NULL) {
|
||||
LOG(DEBUG) << "Radio is NULL, waiting 1 minute to retry";
|
||||
sleep(60);
|
||||
radio = IRadio::getService(GetParam());
|
||||
}
|
||||
@@ -70,4 +72,4 @@ void RadioHidlTest::updateSimCardStatus() {
|
||||
serial = GetRandomSerialNumber();
|
||||
radio->getIccCardStatus(serial);
|
||||
EXPECT_EQ(std::cv_status::no_timeout, wait());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,12 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <radio_hidl_hal_utils_v1_0.h>
|
||||
|
||||
/*
|
||||
* Test IRadio.getCurrentCalls() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getCurrentCalls) {
|
||||
LOG(DEBUG) << "getCurrentCalls";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getCurrentCalls(serial);
|
||||
@@ -30,12 +32,14 @@ TEST_P(RadioHidlTest, getCurrentCalls) {
|
||||
if (cardStatus.cardState == CardState::ABSENT) {
|
||||
EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
|
||||
}
|
||||
LOG(DEBUG) << "getCurrentCalls finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.dial() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, dial) {
|
||||
LOG(DEBUG) << "dial";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
Dial dialInfo;
|
||||
@@ -57,12 +61,14 @@ TEST_P(RadioHidlTest, dial) {
|
||||
RadioError::OPERATION_NOT_ALLOWED},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "dial finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.hangup() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, hangup) {
|
||||
LOG(DEBUG) << "hangup";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->hangup(serial, 1);
|
||||
@@ -76,12 +82,14 @@ TEST_P(RadioHidlTest, hangup) {
|
||||
{RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "hangup finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.hangupWaitingOrBackground() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, hangupWaitingOrBackground) {
|
||||
LOG(DEBUG) << "hangupWaitingOrBackground";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->hangupWaitingOrBackground(serial);
|
||||
@@ -94,12 +102,14 @@ TEST_P(RadioHidlTest, hangupWaitingOrBackground) {
|
||||
{RadioError::INVALID_STATE, RadioError::MODEM_ERR},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "hangupWaitingOrBackground finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.hangupForegroundResumeBackground() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, hangupForegroundResumeBackground) {
|
||||
LOG(DEBUG) << "hangupForegroundResumeBackground";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->hangupForegroundResumeBackground(serial);
|
||||
@@ -112,12 +122,14 @@ TEST_P(RadioHidlTest, hangupForegroundResumeBackground) {
|
||||
{RadioError::INVALID_STATE, RadioError::MODEM_ERR},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "hangupForegroundResumeBackground finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.switchWaitingOrHoldingAndActive() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, switchWaitingOrHoldingAndActive) {
|
||||
LOG(DEBUG) << "switchWaitingOrHoldingAndActive";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->switchWaitingOrHoldingAndActive(serial);
|
||||
@@ -130,12 +142,14 @@ TEST_P(RadioHidlTest, switchWaitingOrHoldingAndActive) {
|
||||
{RadioError::INVALID_STATE, RadioError::MODEM_ERR},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "switchWaitingOrHoldingAndActive finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.conference() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, conference) {
|
||||
LOG(DEBUG) << "conference";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->conference(serial);
|
||||
@@ -148,12 +162,14 @@ TEST_P(RadioHidlTest, conference) {
|
||||
{RadioError::INVALID_STATE, RadioError::MODEM_ERR},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "conference finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.rejectCall() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, rejectCall) {
|
||||
LOG(DEBUG) << "rejectCall";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->rejectCall(serial);
|
||||
@@ -166,12 +182,14 @@ TEST_P(RadioHidlTest, rejectCall) {
|
||||
{RadioError::INVALID_STATE, RadioError::MODEM_ERR},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "rejectCall finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getLastCallFailCause() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getLastCallFailCause) {
|
||||
LOG(DEBUG) << "getLastCallFailCause";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getLastCallFailCause(serial);
|
||||
@@ -183,12 +201,14 @@ TEST_P(RadioHidlTest, getLastCallFailCause) {
|
||||
ASSERT_TRUE(
|
||||
CheckAnyOfErrors(radioRsp->rspInfo.error, {RadioError::NONE}, CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "getLastCallFailCause finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.sendUssd() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, sendUssd) {
|
||||
LOG(DEBUG) << "sendUssd";
|
||||
serial = GetRandomSerialNumber();
|
||||
radio->sendUssd(serial, hidl_string("test"));
|
||||
EXPECT_EQ(std::cv_status::no_timeout, wait());
|
||||
@@ -201,12 +221,14 @@ TEST_P(RadioHidlTest, sendUssd) {
|
||||
{RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "sendUssd finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.cancelPendingUssd() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, cancelPendingUssd) {
|
||||
LOG(DEBUG) << "cancelPendingUssd";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->cancelPendingUssd(serial);
|
||||
@@ -220,12 +242,14 @@ TEST_P(RadioHidlTest, cancelPendingUssd) {
|
||||
{RadioError::NONE, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "cancelPendingUssd finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getCallForwardStatus() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getCallForwardStatus) {
|
||||
LOG(DEBUG) << "getCallForwardStatus";
|
||||
serial = GetRandomSerialNumber();
|
||||
CallForwardInfo callInfo;
|
||||
memset(&callInfo, 0, sizeof(callInfo));
|
||||
@@ -242,12 +266,14 @@ TEST_P(RadioHidlTest, getCallForwardStatus) {
|
||||
{RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "getCallForwardStatus finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setCallForward() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setCallForward) {
|
||||
LOG(DEBUG) << "setCallForward";
|
||||
serial = GetRandomSerialNumber();
|
||||
CallForwardInfo callInfo;
|
||||
memset(&callInfo, 0, sizeof(callInfo));
|
||||
@@ -264,12 +290,14 @@ TEST_P(RadioHidlTest, setCallForward) {
|
||||
{RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "setCallForward finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getCallWaiting() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getCallWaiting) {
|
||||
LOG(DEBUG) << "getCallWaiting";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getCallWaiting(serial, 1);
|
||||
@@ -283,12 +311,14 @@ TEST_P(RadioHidlTest, getCallWaiting) {
|
||||
{RadioError::NONE, RadioError::INVALID_ARGUMENTS, RadioError::MODEM_ERR},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "getCallWaiting finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setCallWaiting() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setCallWaiting) {
|
||||
LOG(DEBUG) << "setCallWaiting";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->setCallWaiting(serial, true, 1);
|
||||
@@ -302,12 +332,14 @@ TEST_P(RadioHidlTest, setCallWaiting) {
|
||||
{RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "setCallWaiting finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.acceptCall() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, acceptCall) {
|
||||
LOG(DEBUG) << "acceptCall";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->acceptCall(serial);
|
||||
@@ -320,12 +352,14 @@ TEST_P(RadioHidlTest, acceptCall) {
|
||||
{RadioError::INVALID_STATE, RadioError::MODEM_ERR},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "acceptCall finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.separateConnection() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, separateConnection) {
|
||||
LOG(DEBUG) << "separateConnection";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->separateConnection(serial, 1);
|
||||
@@ -339,12 +373,14 @@ TEST_P(RadioHidlTest, separateConnection) {
|
||||
{RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "separateConnection finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.explicitCallTransfer() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, explicitCallTransfer) {
|
||||
LOG(DEBUG) << "explicitCallTransfer";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->explicitCallTransfer(serial);
|
||||
@@ -357,12 +393,14 @@ TEST_P(RadioHidlTest, explicitCallTransfer) {
|
||||
{RadioError::INVALID_STATE, RadioError::MODEM_ERR},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "explicitCallTransfer finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.sendCDMAFeatureCode() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, sendCDMAFeatureCode) {
|
||||
LOG(DEBUG) << "sendCDMAFeatureCode";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->sendCDMAFeatureCode(serial, hidl_string());
|
||||
@@ -377,12 +415,14 @@ TEST_P(RadioHidlTest, sendCDMAFeatureCode) {
|
||||
RadioError::MODEM_ERR, RadioError::OPERATION_NOT_ALLOWED},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "sendCDMAFeatureCode finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.sendDtmf() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, sendDtmf) {
|
||||
LOG(DEBUG) << "sendDtmf";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->sendDtmf(serial, "1");
|
||||
@@ -397,12 +437,14 @@ TEST_P(RadioHidlTest, sendDtmf) {
|
||||
RadioError::INVALID_MODEM_STATE, RadioError::MODEM_ERR},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "sendDtmf finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.startDtmf() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, startDtmf) {
|
||||
LOG(DEBUG) << "startDtmf";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->startDtmf(serial, "1");
|
||||
@@ -417,12 +459,14 @@ TEST_P(RadioHidlTest, startDtmf) {
|
||||
RadioError::INVALID_MODEM_STATE, RadioError::MODEM_ERR},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "startDtmf finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.stopDtmf() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, stopDtmf) {
|
||||
LOG(DEBUG) << "stopDtmf";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->stopDtmf(serial);
|
||||
@@ -436,12 +480,14 @@ TEST_P(RadioHidlTest, stopDtmf) {
|
||||
RadioError::INVALID_MODEM_STATE, RadioError::MODEM_ERR},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "stopDtmf finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setMute() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, setMute) {
|
||||
LOG(DEBUG) << "setMute";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->setMute(serial, true);
|
||||
@@ -454,12 +500,14 @@ TEST_P(RadioHidlTest, setMute) {
|
||||
{RadioError::NONE, RadioError::INVALID_ARGUMENTS},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "setMute finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.getMute() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, getMute) {
|
||||
LOG(DEBUG) << "getMute";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->getMute(serial);
|
||||
@@ -470,12 +518,14 @@ TEST_P(RadioHidlTest, getMute) {
|
||||
if (cardStatus.cardState == CardState::ABSENT) {
|
||||
EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
|
||||
}
|
||||
LOG(DEBUG) << "getMute finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.sendBurstDtmf() for the response returned.
|
||||
*/
|
||||
TEST_P(RadioHidlTest, sendBurstDtmf) {
|
||||
LOG(DEBUG) << "sendBurstDtmf";
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
radio->sendBurstDtmf(serial, "1", 0, 0);
|
||||
@@ -489,4 +539,5 @@ TEST_P(RadioHidlTest, sendBurstDtmf) {
|
||||
RadioError::MODEM_ERR, RadioError::OPERATION_NOT_ALLOWED},
|
||||
CHECK_GENERAL_ERROR));
|
||||
}
|
||||
LOG(DEBUG) << "sendBurstDtmf finished";
|
||||
}
|
||||
|
||||
@@ -14,12 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <sap_hidl_hal_utils.h>
|
||||
|
||||
/*
|
||||
* Test ISap.connectReq() for the response returned.
|
||||
*/
|
||||
TEST_P(SapHidlTest, connectReq) {
|
||||
LOG(DEBUG) << "connectReq";
|
||||
token = GetRandomSerialNumber();
|
||||
int32_t maxMsgSize = 100;
|
||||
|
||||
@@ -30,23 +32,27 @@ TEST_P(SapHidlTest, connectReq) {
|
||||
// Modem side need time for connect to finish. Adding a waiting time to prevent
|
||||
// disconnect being requested right after connect request.
|
||||
sleep(1);
|
||||
LOG(DEBUG) << "connectReq finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.disconnectReq() for the response returned
|
||||
*/
|
||||
TEST_P(SapHidlTest, disconnectReq) {
|
||||
LOG(DEBUG) << "disconnectReq";
|
||||
token = GetRandomSerialNumber();
|
||||
|
||||
sap->disconnectReq(token);
|
||||
EXPECT_EQ(std::cv_status::no_timeout, wait());
|
||||
EXPECT_EQ(sapCb->sapResponseToken, token);
|
||||
LOG(DEBUG) << "disconnectReq finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.apduReq() for the response returned.
|
||||
*/
|
||||
TEST_P(SapHidlTest, apduReq) {
|
||||
LOG(DEBUG) << "apduReq";
|
||||
token = GetRandomSerialNumber();
|
||||
SapApduType sapApduType = SapApduType::APDU;
|
||||
android::hardware::hidl_vec<uint8_t> command = {};
|
||||
@@ -59,12 +65,14 @@ TEST_P(SapHidlTest, apduReq) {
|
||||
CheckAnyOfErrors(sapCb->sapResultCode,
|
||||
{SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_ALREADY_POWERED_OFF,
|
||||
SapResultCode::CARD_NOT_ACCESSSIBLE, SapResultCode::CARD_REMOVED}));
|
||||
LOG(DEBUG) << "apduReq finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.transferAtrReq() for the response returned.
|
||||
*/
|
||||
TEST_P(SapHidlTest, transferAtrReq) {
|
||||
LOG(DEBUG) << "transferAtrReq";
|
||||
token = GetRandomSerialNumber();
|
||||
|
||||
sap->transferAtrReq(token);
|
||||
@@ -75,12 +83,14 @@ TEST_P(SapHidlTest, transferAtrReq) {
|
||||
CheckAnyOfErrors(sapCb->sapResultCode,
|
||||
{SapResultCode::GENERIC_FAILURE, SapResultCode::DATA_NOT_AVAILABLE,
|
||||
SapResultCode::CARD_ALREADY_POWERED_OFF, SapResultCode::CARD_REMOVED}));
|
||||
LOG(DEBUG) << "transferAtrReq finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.powerReq() for the response returned.
|
||||
*/
|
||||
TEST_P(SapHidlTest, powerReq) {
|
||||
LOG(DEBUG) << "powerReq";
|
||||
token = GetRandomSerialNumber();
|
||||
bool state = true;
|
||||
|
||||
@@ -92,12 +102,14 @@ TEST_P(SapHidlTest, powerReq) {
|
||||
sapCb->sapResultCode, {SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_NOT_ACCESSSIBLE,
|
||||
SapResultCode::CARD_ALREADY_POWERED_OFF, SapResultCode::CARD_REMOVED,
|
||||
SapResultCode::CARD_ALREADY_POWERED_ON}));
|
||||
LOG(DEBUG) << "powerReq finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.resetSimReq() for the response returned.
|
||||
*/
|
||||
TEST_P(SapHidlTest, resetSimReq) {
|
||||
LOG(DEBUG) << "resetSimReq";
|
||||
token = GetRandomSerialNumber();
|
||||
|
||||
sap->resetSimReq(token);
|
||||
@@ -108,12 +120,14 @@ TEST_P(SapHidlTest, resetSimReq) {
|
||||
CheckAnyOfErrors(sapCb->sapResultCode,
|
||||
{SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_NOT_ACCESSSIBLE,
|
||||
SapResultCode::CARD_ALREADY_POWERED_OFF, SapResultCode::CARD_REMOVED}));
|
||||
LOG(DEBUG) << "resetSimReq finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.transferCardReaderStatusReq() for the response returned.
|
||||
*/
|
||||
TEST_P(SapHidlTest, transferCardReaderStatusReq) {
|
||||
LOG(DEBUG) << "transferCardReaderStatusReq";
|
||||
token = GetRandomSerialNumber();
|
||||
|
||||
sap->transferCardReaderStatusReq(token);
|
||||
@@ -122,12 +136,14 @@ TEST_P(SapHidlTest, transferCardReaderStatusReq) {
|
||||
|
||||
ASSERT_TRUE(CheckAnyOfErrors(
|
||||
sapCb->sapResultCode, {SapResultCode::GENERIC_FAILURE, SapResultCode::DATA_NOT_AVAILABLE}));
|
||||
LOG(DEBUG) << "transferCardReaderStatusReq finished";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test IRadio.setTransferProtocolReq() for the response returned.
|
||||
*/
|
||||
TEST_P(SapHidlTest, setTransferProtocolReq) {
|
||||
LOG(DEBUG) << "setTransferProtocolReq";
|
||||
token = GetRandomSerialNumber();
|
||||
SapTransferProtocol sapTransferProtocol = SapTransferProtocol::T0;
|
||||
|
||||
@@ -136,4 +152,5 @@ TEST_P(SapHidlTest, setTransferProtocolReq) {
|
||||
EXPECT_EQ(sapCb->sapResponseToken, token);
|
||||
|
||||
EXPECT_EQ(SapResultCode::NOT_SUPPORTED, sapCb->sapResultCode);
|
||||
LOG(DEBUG) << "setTransferProtocolReq finished";
|
||||
}
|
||||
|
||||
@@ -30,5 +30,6 @@
|
||||
<test class="com.android.tradefed.testtype.GTest" >
|
||||
<option name="native-test-device-path" value="/data/local/tmp" />
|
||||
<option name="module-name" value="VtsHalRadioV1_0TargetTest" />
|
||||
<option name="native-test-timeout" value="300000" /> <!-- 5 min -->
|
||||
</test>
|
||||
</configuration>
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
<target_preparer class="com.android.tradefed.targetprep.MultiSimPreparer" />
|
||||
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
|
||||
|
||||
<target_preparer class="com.android.tradefed.targetprep.StopServicesSetup"/>
|
||||
|
||||
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
|
||||
<option name="cleanup" value="true" />
|
||||
<option name="push" value="VtsHalSapV1_0TargetTest->/data/local/tmp/VtsHalSapV1_0TargetTest" />
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
<test class="com.android.tradefed.testtype.GTest" >
|
||||
<option name="native-test-device-path" value="/data/local/tmp" />
|
||||
<option name="native-test-timeout" value="300000" /> <!-- 5 min -->
|
||||
<option name="module-name" value="VtsHalRadioV1_1TargetTest" />
|
||||
</test>
|
||||
</configuration>
|
||||
|
||||
@@ -49,7 +49,6 @@ TEST_P(RadioHidlTest_v1_1, setSimCardPower_1_1) {
|
||||
}
|
||||
EXPECT_EQ(CardState::ABSENT, cardStatus.cardState);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Test setSimCardPower power up */
|
||||
serial = GetRandomSerialNumber();
|
||||
@@ -60,6 +59,7 @@ TEST_P(RadioHidlTest_v1_1, setSimCardPower_1_1) {
|
||||
ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_1->rspInfo.error,
|
||||
{RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED,
|
||||
RadioError::INVALID_ARGUMENTS, RadioError::RADIO_NOT_AVAILABLE}));
|
||||
#endif
|
||||
|
||||
/**
|
||||
* If the sim card status for the testing environment is PRESENT,
|
||||
|
||||
@@ -735,7 +735,7 @@ TEST_P(RadioHidlTest_v1_2, getDataRegistrationState) {
|
||||
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
|
||||
EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
|
||||
|
||||
ALOGI("getVoiceRegistrationStateResponse_1_2, rspInfo.error = %s\n",
|
||||
ALOGI("getDataRegistrationStateResponse_1_2, rspInfo.error = %s\n",
|
||||
toString(radioRsp_v1_2->rspInfo.error).c_str());
|
||||
ASSERT_TRUE(CheckAnyOfErrors(
|
||||
radioRsp_v1_2->rspInfo.error,
|
||||
|
||||
@@ -18,6 +18,15 @@
|
||||
|
||||
#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
|
||||
|
||||
namespace {
|
||||
const RadioAccessSpecifier GERAN_SPECIFIER_P900 = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
|
||||
.geranBands = {GeranBands::BAND_P900},
|
||||
.channels = {1, 2}};
|
||||
const RadioAccessSpecifier GERAN_SPECIFIER_850 = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
|
||||
.geranBands = {GeranBands::BAND_850},
|
||||
.channels = {128, 129}};
|
||||
} // namespace
|
||||
|
||||
/*
|
||||
* Test IRadio.emergencyDial() for the response returned.
|
||||
*/
|
||||
@@ -199,14 +208,10 @@ TEST_P(RadioHidlTest_v1_4, setPreferredNetworkTypeBitmap) {
|
||||
TEST_P(RadioHidlTest_v1_4, startNetworkScan) {
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
|
||||
.geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
|
||||
.channels = {1, 2}};
|
||||
|
||||
::android::hardware::radio::V1_2::NetworkScanRequest request = {
|
||||
.type = ScanType::ONE_SHOT,
|
||||
.interval = 60,
|
||||
.specifiers = {specifier},
|
||||
.specifiers = {::GERAN_SPECIFIER_P900, ::GERAN_SPECIFIER_850},
|
||||
.maxSearchTime = 60,
|
||||
.incrementalResults = false,
|
||||
.incrementalResultsPeriodicity = 1};
|
||||
@@ -234,6 +239,11 @@ TEST_P(RadioHidlTest_v1_4, startNetworkScan) {
|
||||
{RadioError::NONE, RadioError::OPERATION_NOT_ALLOWED,
|
||||
RadioError::REQUEST_NOT_SUPPORTED}));
|
||||
}
|
||||
|
||||
if (radioRsp_v1_4->rspInfo.error == RadioError::NONE) {
|
||||
ALOGI("Stop Network Scan");
|
||||
stopNetworkScan();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -270,14 +280,10 @@ TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidArgument) {
|
||||
TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidInterval1) {
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
|
||||
.geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
|
||||
.channels = {1, 2}};
|
||||
|
||||
::android::hardware::radio::V1_2::NetworkScanRequest request = {
|
||||
.type = ScanType::ONE_SHOT,
|
||||
.interval = 4,
|
||||
.specifiers = {specifier},
|
||||
.specifiers = {::GERAN_SPECIFIER_P900, ::GERAN_SPECIFIER_850},
|
||||
.maxSearchTime = 60,
|
||||
.incrementalResults = false,
|
||||
.incrementalResultsPeriodicity = 1};
|
||||
@@ -307,14 +313,10 @@ TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidInterval1) {
|
||||
TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidInterval2) {
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
|
||||
.geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
|
||||
.channels = {1, 2}};
|
||||
|
||||
::android::hardware::radio::V1_2::NetworkScanRequest request = {
|
||||
.type = ScanType::ONE_SHOT,
|
||||
.interval = 301,
|
||||
.specifiers = {specifier},
|
||||
.specifiers = {::GERAN_SPECIFIER_P900, ::GERAN_SPECIFIER_850},
|
||||
.maxSearchTime = 60,
|
||||
.incrementalResults = false,
|
||||
.incrementalResultsPeriodicity = 1};
|
||||
@@ -343,14 +345,10 @@ TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidInterval2) {
|
||||
TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidMaxSearchTime1) {
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
|
||||
.geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
|
||||
.channels = {1, 2}};
|
||||
|
||||
::android::hardware::radio::V1_2::NetworkScanRequest request = {
|
||||
.type = ScanType::ONE_SHOT,
|
||||
.interval = 60,
|
||||
.specifiers = {specifier},
|
||||
.specifiers = {::GERAN_SPECIFIER_P900, ::GERAN_SPECIFIER_850},
|
||||
.maxSearchTime = 59,
|
||||
.incrementalResults = false,
|
||||
.incrementalResultsPeriodicity = 1};
|
||||
@@ -379,14 +377,10 @@ TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidMaxSearchTime1) {
|
||||
TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidMaxSearchTime2) {
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
|
||||
.geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
|
||||
.channels = {1, 2}};
|
||||
|
||||
::android::hardware::radio::V1_2::NetworkScanRequest request = {
|
||||
.type = ScanType::ONE_SHOT,
|
||||
.interval = 60,
|
||||
.specifiers = {specifier},
|
||||
.specifiers = {::GERAN_SPECIFIER_P900, ::GERAN_SPECIFIER_850},
|
||||
.maxSearchTime = 3601,
|
||||
.incrementalResults = false,
|
||||
.incrementalResultsPeriodicity = 1};
|
||||
@@ -415,14 +409,10 @@ TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidMaxSearchTime2) {
|
||||
TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidPeriodicity1) {
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
|
||||
.geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
|
||||
.channels = {1, 2}};
|
||||
|
||||
::android::hardware::radio::V1_2::NetworkScanRequest request = {
|
||||
.type = ScanType::ONE_SHOT,
|
||||
.interval = 60,
|
||||
.specifiers = {specifier},
|
||||
.specifiers = {::GERAN_SPECIFIER_P900, ::GERAN_SPECIFIER_850},
|
||||
.maxSearchTime = 600,
|
||||
.incrementalResults = true,
|
||||
.incrementalResultsPeriodicity = 0};
|
||||
@@ -451,14 +441,10 @@ TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidPeriodicity1) {
|
||||
TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidPeriodicity2) {
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
|
||||
.geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
|
||||
.channels = {1, 2}};
|
||||
|
||||
::android::hardware::radio::V1_2::NetworkScanRequest request = {
|
||||
.type = ScanType::ONE_SHOT,
|
||||
.interval = 60,
|
||||
.specifiers = {specifier},
|
||||
.specifiers = {::GERAN_SPECIFIER_P900, ::GERAN_SPECIFIER_850},
|
||||
.maxSearchTime = 600,
|
||||
.incrementalResults = true,
|
||||
.incrementalResultsPeriodicity = 11};
|
||||
@@ -487,14 +473,10 @@ TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidPeriodicity2) {
|
||||
TEST_P(RadioHidlTest_v1_4, startNetworkScan_GoodRequest1) {
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
|
||||
.geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
|
||||
.channels = {1, 2}};
|
||||
|
||||
::android::hardware::radio::V1_2::NetworkScanRequest request = {
|
||||
.type = ScanType::ONE_SHOT,
|
||||
.interval = 60,
|
||||
.specifiers = {specifier},
|
||||
.specifiers = {::GERAN_SPECIFIER_P900, ::GERAN_SPECIFIER_850},
|
||||
// Some vendor may not support max search time of 360s.
|
||||
// This issue is tracked in b/112205669.
|
||||
.maxSearchTime = 300,
|
||||
@@ -518,6 +500,11 @@ TEST_P(RadioHidlTest_v1_4, startNetworkScan_GoodRequest1) {
|
||||
{RadioError::NONE, RadioError::INVALID_ARGUMENTS,
|
||||
RadioError::REQUEST_NOT_SUPPORTED}));
|
||||
}
|
||||
|
||||
if (radioRsp_v1_4->rspInfo.error == RadioError::NONE) {
|
||||
ALOGI("Stop Network Scan");
|
||||
stopNetworkScan();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -526,14 +513,10 @@ TEST_P(RadioHidlTest_v1_4, startNetworkScan_GoodRequest1) {
|
||||
TEST_P(RadioHidlTest_v1_4, startNetworkScan_GoodRequest2) {
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
|
||||
.geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
|
||||
.channels = {1, 2}};
|
||||
|
||||
::android::hardware::radio::V1_2::NetworkScanRequest request = {
|
||||
.type = ScanType::ONE_SHOT,
|
||||
.interval = 60,
|
||||
.specifiers = {specifier},
|
||||
.specifiers = {::GERAN_SPECIFIER_P900, ::GERAN_SPECIFIER_850},
|
||||
// Some vendor may not support max search time of 360s.
|
||||
// This issue is tracked in b/112205669.
|
||||
.maxSearchTime = 300,
|
||||
@@ -559,6 +542,11 @@ TEST_P(RadioHidlTest_v1_4, startNetworkScan_GoodRequest2) {
|
||||
{RadioError::NONE, RadioError::INVALID_ARGUMENTS,
|
||||
RadioError::REQUEST_NOT_SUPPORTED}));
|
||||
}
|
||||
|
||||
if (radioRsp_v1_4->rspInfo.error == RadioError::NONE) {
|
||||
ALOGI("Stop Network Scan");
|
||||
stopNetworkScan();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -107,3 +107,9 @@ void RadioHidlTest_v1_4::updateSimCardStatus() {
|
||||
radio_v1_4->getIccCardStatus(serial);
|
||||
EXPECT_EQ(std::cv_status::no_timeout, wait());
|
||||
}
|
||||
|
||||
void RadioHidlTest_v1_4::stopNetworkScan() {
|
||||
serial = GetRandomSerialNumber();
|
||||
radio_v1_4->stopNetworkScan(serial);
|
||||
EXPECT_EQ(std::cv_status::no_timeout, wait());
|
||||
}
|
||||
|
||||
@@ -721,7 +721,10 @@ class RadioHidlTest_v1_4 : public ::testing::TestWithParam<std::string> {
|
||||
/* Update Sim Card Status */
|
||||
void updateSimCardStatus();
|
||||
|
||||
public:
|
||||
/* Stop Network Scan Command */
|
||||
void stopNetworkScan();
|
||||
|
||||
public:
|
||||
virtual void SetUp() override;
|
||||
|
||||
/* Used as a mechanism to inform the test about data/event callback */
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <android-base/properties.h>
|
||||
#include <radio_hidl_hal_utils_v1_5.h>
|
||||
|
||||
#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
|
||||
@@ -248,7 +249,7 @@ TEST_P(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_NGRAN_SSRSRQ)
|
||||
signalThresholdInfo.signalMeasurement = SignalMeasurementType::SSRSRQ;
|
||||
signalThresholdInfo.hysteresisMs = 5000;
|
||||
signalThresholdInfo.hysteresisDb = 0;
|
||||
signalThresholdInfo.thresholds = {-15, -10, -5, -4};
|
||||
signalThresholdInfo.thresholds = {-43, -20, 0, 20};
|
||||
signalThresholdInfo.isEnabled = true;
|
||||
|
||||
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
|
||||
@@ -502,15 +503,21 @@ TEST_P(RadioHidlTest_v1_5, areUiccApplicationsEnabled) {
|
||||
TEST_P(RadioHidlTest_v1_5, setSystemSelectionChannels_1_5) {
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
|
||||
rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
|
||||
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands bandP900;
|
||||
bandP900.geranBands() = {GeranBands::BAND_P900};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands band850;
|
||||
band850.geranBands() = {GeranBands::BAND_850};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifierP900 = {
|
||||
.radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
|
||||
.bands = rasBands,
|
||||
.bands = bandP900,
|
||||
.channels = {1, 2}};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifier850 = {
|
||||
.radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
|
||||
.bands = band850,
|
||||
.channels = {128, 129}};
|
||||
|
||||
Return<void> res = radio_v1_5->setSystemSelectionChannels_1_5(serial, true, {specifier});
|
||||
Return<void> res =
|
||||
radio_v1_5->setSystemSelectionChannels_1_5(serial, true, {specifierP900, specifier850});
|
||||
ASSERT_OK(res);
|
||||
EXPECT_EQ(std::cv_status::no_timeout, wait());
|
||||
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
|
||||
@@ -523,7 +530,8 @@ TEST_P(RadioHidlTest_v1_5, setSystemSelectionChannels_1_5) {
|
||||
|
||||
if (radioRsp_v1_5->rspInfo.error == RadioError::NONE) {
|
||||
serial = GetRandomSerialNumber();
|
||||
Return<void> res = radio_v1_5->setSystemSelectionChannels_1_5(serial, false, {specifier});
|
||||
Return<void> res = radio_v1_5->setSystemSelectionChannels_1_5(
|
||||
serial, false, {specifierP900, specifier850});
|
||||
ASSERT_OK(res);
|
||||
EXPECT_EQ(std::cv_status::no_timeout, wait());
|
||||
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
|
||||
@@ -540,18 +548,23 @@ TEST_P(RadioHidlTest_v1_5, setSystemSelectionChannels_1_5) {
|
||||
TEST_P(RadioHidlTest_v1_5, startNetworkScan) {
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
|
||||
rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
|
||||
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands bandP900;
|
||||
bandP900.geranBands() = {GeranBands::BAND_P900};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands band850;
|
||||
band850.geranBands() = {GeranBands::BAND_850};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifierP900 = {
|
||||
.radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
|
||||
.bands = rasBands,
|
||||
.bands = bandP900,
|
||||
.channels = {1, 2}};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifier850 = {
|
||||
.radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
|
||||
.bands = band850,
|
||||
.channels = {128, 129}};
|
||||
|
||||
::android::hardware::radio::V1_5::NetworkScanRequest request = {
|
||||
.type = ScanType::ONE_SHOT,
|
||||
.interval = 60,
|
||||
.specifiers = {specifier},
|
||||
.specifiers = {specifierP900, specifier850},
|
||||
.maxSearchTime = 60,
|
||||
.incrementalResults = false,
|
||||
.incrementalResultsPeriodicity = 1};
|
||||
@@ -573,6 +586,11 @@ TEST_P(RadioHidlTest_v1_5, startNetworkScan) {
|
||||
ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
|
||||
{RadioError::NONE, RadioError::OPERATION_NOT_ALLOWED}));
|
||||
}
|
||||
|
||||
if (radioRsp_v1_5->rspInfo.error == RadioError::NONE) {
|
||||
ALOGI("Stop Network Scan");
|
||||
stopNetworkScan();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -608,18 +626,23 @@ TEST_P(RadioHidlTest_v1_5, startNetworkScan_InvalidArgument) {
|
||||
TEST_P(RadioHidlTest_v1_5, startNetworkScan_InvalidInterval1) {
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
|
||||
rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
|
||||
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands bandP900;
|
||||
bandP900.geranBands() = {GeranBands::BAND_P900};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands band850;
|
||||
band850.geranBands() = {GeranBands::BAND_850};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifierP900 = {
|
||||
.radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
|
||||
.bands = rasBands,
|
||||
.bands = bandP900,
|
||||
.channels = {1, 2}};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifier850 = {
|
||||
.radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
|
||||
.bands = band850,
|
||||
.channels = {128, 129}};
|
||||
|
||||
::android::hardware::radio::V1_5::NetworkScanRequest request = {
|
||||
.type = ScanType::ONE_SHOT,
|
||||
.interval = 4,
|
||||
.specifiers = {specifier},
|
||||
.specifiers = {specifierP900, specifier850},
|
||||
.maxSearchTime = 60,
|
||||
.incrementalResults = false,
|
||||
.incrementalResultsPeriodicity = 1};
|
||||
@@ -647,18 +670,23 @@ TEST_P(RadioHidlTest_v1_5, startNetworkScan_InvalidInterval1) {
|
||||
TEST_P(RadioHidlTest_v1_5, startNetworkScan_InvalidInterval2) {
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
|
||||
rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
|
||||
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands bandP900;
|
||||
bandP900.geranBands() = {GeranBands::BAND_P900};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands band850;
|
||||
band850.geranBands() = {GeranBands::BAND_850};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifierP900 = {
|
||||
.radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
|
||||
.bands = rasBands,
|
||||
.bands = bandP900,
|
||||
.channels = {1, 2}};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifier850 = {
|
||||
.radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
|
||||
.bands = band850,
|
||||
.channels = {128, 129}};
|
||||
|
||||
::android::hardware::radio::V1_5::NetworkScanRequest request = {
|
||||
.type = ScanType::ONE_SHOT,
|
||||
.interval = 301,
|
||||
.specifiers = {specifier},
|
||||
.specifiers = {specifierP900, specifier850},
|
||||
.maxSearchTime = 60,
|
||||
.incrementalResults = false,
|
||||
.incrementalResultsPeriodicity = 1};
|
||||
@@ -686,18 +714,23 @@ TEST_P(RadioHidlTest_v1_5, startNetworkScan_InvalidInterval2) {
|
||||
TEST_P(RadioHidlTest_v1_5, startNetworkScan_InvalidMaxSearchTime1) {
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
|
||||
rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
|
||||
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands bandP900;
|
||||
bandP900.geranBands() = {GeranBands::BAND_P900};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands band850;
|
||||
band850.geranBands() = {GeranBands::BAND_850};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifierP900 = {
|
||||
.radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
|
||||
.bands = rasBands,
|
||||
.bands = bandP900,
|
||||
.channels = {1, 2}};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifier850 = {
|
||||
.radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
|
||||
.bands = band850,
|
||||
.channels = {128, 129}};
|
||||
|
||||
::android::hardware::radio::V1_5::NetworkScanRequest request = {
|
||||
.type = ScanType::ONE_SHOT,
|
||||
.interval = 60,
|
||||
.specifiers = {specifier},
|
||||
.specifiers = {specifierP900, specifier850},
|
||||
.maxSearchTime = 59,
|
||||
.incrementalResults = false,
|
||||
.incrementalResultsPeriodicity = 1};
|
||||
@@ -725,18 +758,23 @@ TEST_P(RadioHidlTest_v1_5, startNetworkScan_InvalidMaxSearchTime1) {
|
||||
TEST_P(RadioHidlTest_v1_5, startNetworkScan_InvalidMaxSearchTime2) {
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
|
||||
rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
|
||||
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands bandP900;
|
||||
bandP900.geranBands() = {GeranBands::BAND_P900};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands band850;
|
||||
band850.geranBands() = {GeranBands::BAND_850};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifierP900 = {
|
||||
.radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
|
||||
.bands = rasBands,
|
||||
.bands = bandP900,
|
||||
.channels = {1, 2}};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifier850 = {
|
||||
.radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
|
||||
.bands = band850,
|
||||
.channels = {128, 129}};
|
||||
|
||||
::android::hardware::radio::V1_5::NetworkScanRequest request = {
|
||||
.type = ScanType::ONE_SHOT,
|
||||
.interval = 60,
|
||||
.specifiers = {specifier},
|
||||
.specifiers = {specifierP900, specifier850},
|
||||
.maxSearchTime = 3601,
|
||||
.incrementalResults = false,
|
||||
.incrementalResultsPeriodicity = 1};
|
||||
@@ -764,18 +802,23 @@ TEST_P(RadioHidlTest_v1_5, startNetworkScan_InvalidMaxSearchTime2) {
|
||||
TEST_P(RadioHidlTest_v1_5, startNetworkScan_InvalidPeriodicity1) {
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
|
||||
rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
|
||||
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands bandP900;
|
||||
bandP900.geranBands() = {GeranBands::BAND_P900};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands band850;
|
||||
band850.geranBands() = {GeranBands::BAND_850};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifierP900 = {
|
||||
.radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
|
||||
.bands = rasBands,
|
||||
.bands = bandP900,
|
||||
.channels = {1, 2}};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifier850 = {
|
||||
.radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
|
||||
.bands = band850,
|
||||
.channels = {128, 129}};
|
||||
|
||||
::android::hardware::radio::V1_5::NetworkScanRequest request = {
|
||||
.type = ScanType::ONE_SHOT,
|
||||
.interval = 60,
|
||||
.specifiers = {specifier},
|
||||
.specifiers = {specifierP900, specifier850},
|
||||
.maxSearchTime = 600,
|
||||
.incrementalResults = true,
|
||||
.incrementalResultsPeriodicity = 0};
|
||||
@@ -803,18 +846,23 @@ TEST_P(RadioHidlTest_v1_5, startNetworkScan_InvalidPeriodicity1) {
|
||||
TEST_P(RadioHidlTest_v1_5, startNetworkScan_InvalidPeriodicity2) {
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
|
||||
rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
|
||||
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands bandP900;
|
||||
bandP900.geranBands() = {GeranBands::BAND_P900};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands band850;
|
||||
band850.geranBands() = {GeranBands::BAND_850};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifierP900 = {
|
||||
.radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
|
||||
.bands = rasBands,
|
||||
.bands = bandP900,
|
||||
.channels = {1, 2}};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifier850 = {
|
||||
.radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
|
||||
.bands = band850,
|
||||
.channels = {128, 129}};
|
||||
|
||||
::android::hardware::radio::V1_5::NetworkScanRequest request = {
|
||||
.type = ScanType::ONE_SHOT,
|
||||
.interval = 60,
|
||||
.specifiers = {specifier},
|
||||
.specifiers = {specifierP900, specifier850},
|
||||
.maxSearchTime = 600,
|
||||
.incrementalResults = true,
|
||||
.incrementalResultsPeriodicity = 11};
|
||||
@@ -842,18 +890,23 @@ TEST_P(RadioHidlTest_v1_5, startNetworkScan_InvalidPeriodicity2) {
|
||||
TEST_P(RadioHidlTest_v1_5, startNetworkScan_GoodRequest1) {
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
|
||||
rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
|
||||
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands bandP900;
|
||||
bandP900.geranBands() = {GeranBands::BAND_P900};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands band850;
|
||||
band850.geranBands() = {GeranBands::BAND_850};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifierP900 = {
|
||||
.radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
|
||||
.bands = rasBands,
|
||||
.bands = bandP900,
|
||||
.channels = {1, 2}};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifier850 = {
|
||||
.radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
|
||||
.bands = band850,
|
||||
.channels = {128, 129}};
|
||||
|
||||
::android::hardware::radio::V1_5::NetworkScanRequest request = {
|
||||
.type = ScanType::ONE_SHOT,
|
||||
.interval = 60,
|
||||
.specifiers = {specifier},
|
||||
.specifiers = {specifierP900, specifier850},
|
||||
.maxSearchTime = 360,
|
||||
.incrementalResults = false,
|
||||
.incrementalResultsPeriodicity = 10};
|
||||
@@ -873,6 +926,11 @@ TEST_P(RadioHidlTest_v1_5, startNetworkScan_GoodRequest1) {
|
||||
{RadioError::NONE, RadioError::INVALID_ARGUMENTS,
|
||||
RadioError::REQUEST_NOT_SUPPORTED}));
|
||||
}
|
||||
|
||||
if (radioRsp_v1_5->rspInfo.error == RadioError::NONE) {
|
||||
ALOGI("Stop Network Scan");
|
||||
stopNetworkScan();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -881,18 +939,23 @@ TEST_P(RadioHidlTest_v1_5, startNetworkScan_GoodRequest1) {
|
||||
TEST_P(RadioHidlTest_v1_5, startNetworkScan_GoodRequest2) {
|
||||
serial = GetRandomSerialNumber();
|
||||
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
|
||||
rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
|
||||
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands bandP900;
|
||||
bandP900.geranBands() = {GeranBands::BAND_P900};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands band850;
|
||||
band850.geranBands() = {GeranBands::BAND_850};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifierP900 = {
|
||||
.radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
|
||||
.bands = rasBands,
|
||||
.bands = bandP900,
|
||||
.channels = {1, 2}};
|
||||
::android::hardware::radio::V1_5::RadioAccessSpecifier specifier850 = {
|
||||
.radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
|
||||
.bands = band850,
|
||||
.channels = {128, 129}};
|
||||
|
||||
::android::hardware::radio::V1_5::NetworkScanRequest request = {
|
||||
.type = ScanType::ONE_SHOT,
|
||||
.interval = 60,
|
||||
.specifiers = {specifier},
|
||||
.specifiers = {specifierP900, specifier850},
|
||||
.maxSearchTime = 360,
|
||||
.incrementalResults = false,
|
||||
.incrementalResultsPeriodicity = 10,
|
||||
@@ -913,6 +976,11 @@ TEST_P(RadioHidlTest_v1_5, startNetworkScan_GoodRequest2) {
|
||||
{RadioError::NONE, RadioError::INVALID_ARGUMENTS,
|
||||
RadioError::REQUEST_NOT_SUPPORTED}));
|
||||
}
|
||||
|
||||
if (radioRsp_v1_5->rspInfo.error == RadioError::NONE) {
|
||||
ALOGI("Stop Network Scan");
|
||||
stopNetworkScan();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1174,6 +1242,17 @@ TEST_P(RadioHidlTest_v1_5, getBarringInfo) {
|
||||
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
|
||||
EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
|
||||
|
||||
int32_t firstApiLevel = android::base::GetIntProperty<int32_t>("ro.product.first_api_level", 0);
|
||||
// Allow devices shipping with Radio::1_5 and Android 11 to not support barring info.
|
||||
if (firstApiLevel > 0 && firstApiLevel <= 30) {
|
||||
ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
|
||||
{RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
|
||||
// Early exit for devices that don't support barring info.
|
||||
if (radioRsp_v1_5->rspInfo.error != RadioError::NONE) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT_TRUE(radioRsp_v1_5->barringInfos.size() > 0);
|
||||
|
||||
std::set<BarringInfo::ServiceType> reportedServices;
|
||||
|
||||
@@ -78,3 +78,9 @@ void RadioHidlTest_v1_5::updateSimCardStatus() {
|
||||
radio_v1_5->getIccCardStatus(serial);
|
||||
EXPECT_EQ(std::cv_status::no_timeout, wait());
|
||||
}
|
||||
|
||||
void RadioHidlTest_v1_5::stopNetworkScan() {
|
||||
serial = GetRandomSerialNumber();
|
||||
radio_v1_5->stopNetworkScan(serial);
|
||||
EXPECT_EQ(std::cv_status::no_timeout, wait());
|
||||
}
|
||||
|
||||
@@ -831,6 +831,9 @@ class RadioHidlTest_v1_5 : public ::testing::TestWithParam<std::string> {
|
||||
/* Update Sim Card Status */
|
||||
void updateSimCardStatus();
|
||||
|
||||
/* Stop Network Scan Command */
|
||||
void stopNetworkScan();
|
||||
|
||||
public:
|
||||
virtual void SetUp() override;
|
||||
|
||||
|
||||
@@ -1017,8 +1017,10 @@ Return<void> RadioResponse_v1_5::setNetworkSelectionModeManualResponse_1_5(
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> RadioResponse_v1_5::sendCdmaSmsExpectMoreResponse(const RadioResponseInfo& /*info*/,
|
||||
Return<void> RadioResponse_v1_5::sendCdmaSmsExpectMoreResponse(const RadioResponseInfo& info,
|
||||
const SendSmsResult& /*sms*/) {
|
||||
rspInfo = info;
|
||||
parent_v1_5.notify(info.serial);
|
||||
return Void();
|
||||
}
|
||||
|
||||
|
||||
7
rebootescrow/aidl/vts/functional/README.md
Normal file
7
rebootescrow/aidl/vts/functional/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
Many of the tests in this directory may require that TEE Keymaster
|
||||
"EARLY_BOOT_ONLY" keys be usable when this test runs. In order to accomplish
|
||||
this, a build of "vold" that omits the call to "earlyBootEnded()" function
|
||||
should be made. Then these DISABLED tests may be run successfully.
|
||||
|
||||
The CTS test ResumeOnRebootHostTests will test the functionality without a
|
||||
special build.
|
||||
@@ -60,7 +60,10 @@ class RebootEscrowAidlTest : public testing::TestWithParam<std::string> {
|
||||
};
|
||||
};
|
||||
|
||||
TEST_P(RebootEscrowAidlTest, StoreAndRetrieve_Success) {
|
||||
// This test assumes that it can retrieve keys immediately, but some
|
||||
// implementations use the TEE's EARLY_BOOT_ONLY keys. This means that the
|
||||
// earlyBootEnded() calls will need to be disabled to test this correctly.
|
||||
TEST_P(RebootEscrowAidlTest, DISABLED_StoreAndRetrieve_Success) {
|
||||
SKIP_UNSUPPORTED;
|
||||
|
||||
ASSERT_TRUE(rebootescrow->storeKey(KEY_1).isOk());
|
||||
@@ -70,7 +73,10 @@ TEST_P(RebootEscrowAidlTest, StoreAndRetrieve_Success) {
|
||||
EXPECT_EQ(actualKey, KEY_1);
|
||||
}
|
||||
|
||||
TEST_P(RebootEscrowAidlTest, StoreAndRetrieve_SecondRetrieveSucceeds) {
|
||||
// This test assumes that it can retrieve keys immediately, but some
|
||||
// implementations use the TEE's EARLY_BOOT_ONLY keys. This means that the
|
||||
// earlyBootEnded() calls will need to be disabled to test this correctly.
|
||||
TEST_P(RebootEscrowAidlTest, DISABLED_StoreAndRetrieve_SecondRetrieveSucceeds) {
|
||||
SKIP_UNSUPPORTED;
|
||||
|
||||
ASSERT_TRUE(rebootescrow->storeKey(KEY_1).isOk());
|
||||
@@ -83,7 +89,10 @@ TEST_P(RebootEscrowAidlTest, StoreAndRetrieve_SecondRetrieveSucceeds) {
|
||||
EXPECT_EQ(actualKey, KEY_1);
|
||||
}
|
||||
|
||||
TEST_P(RebootEscrowAidlTest, StoreTwiceOverwrites_Success) {
|
||||
// This test assumes that it can retrieve keys immediately, but some
|
||||
// implementations use the TEE's EARLY_BOOT_ONLY keys. This means that the
|
||||
// earlyBootEnded() calls will need to be disabled to test this correctly.
|
||||
TEST_P(RebootEscrowAidlTest, DISABLED_StoreTwiceOverwrites_Success) {
|
||||
SKIP_UNSUPPORTED;
|
||||
|
||||
ASSERT_TRUE(rebootescrow->storeKey(KEY_1).isOk());
|
||||
@@ -94,7 +103,10 @@ TEST_P(RebootEscrowAidlTest, StoreTwiceOverwrites_Success) {
|
||||
EXPECT_EQ(actualKey, KEY_2);
|
||||
}
|
||||
|
||||
TEST_P(RebootEscrowAidlTest, StoreEmpty_AfterGetEmptyKey_Success) {
|
||||
// This test assumes that it can retrieve keys immediately, but some
|
||||
// implementations use the TEE's EARLY_BOOT_ONLY keys. This means that the
|
||||
// earlyBootEnded() calls will need to be disabled to test this correctly.
|
||||
TEST_P(RebootEscrowAidlTest, DISABLED_StoreEmpty_AfterGetEmptyKey_Success) {
|
||||
SKIP_UNSUPPORTED;
|
||||
|
||||
rebootescrow->storeKey(KEY_1);
|
||||
@@ -105,6 +117,12 @@ TEST_P(RebootEscrowAidlTest, StoreEmpty_AfterGetEmptyKey_Success) {
|
||||
EXPECT_EQ(actualKey, EMPTY_KEY);
|
||||
}
|
||||
|
||||
TEST_P(RebootEscrowAidlTest, Store_Success) {
|
||||
SKIP_UNSUPPORTED;
|
||||
|
||||
rebootescrow->storeKey(KEY_1);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
RebootEscrow, RebootEscrowAidlTest,
|
||||
testing::ValuesIn(android::getAidlHalInstanceNames(IRebootEscrow::descriptor)),
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
hidl_interface {
|
||||
name: "android.hardware.renderscript@1.0",
|
||||
root: "android.hardware",
|
||||
// TODO(b/153609531): remove when no longer needed.
|
||||
native_bridge_supported: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
support_system_process: true,
|
||||
|
||||
@@ -23,11 +23,6 @@ cc_test {
|
||||
"VtsHalSensorsV1_0TargetTest.cpp",
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.graphics.allocator@2.0",
|
||||
"android.hardware.graphics.allocator@3.0",
|
||||
"android.hardware.graphics.mapper@2.0",
|
||||
"android.hardware.graphics.mapper@2.1",
|
||||
"android.hardware.graphics.mapper@3.0",
|
||||
"android.hardware.sensors@1.0",
|
||||
"VtsHalSensorsTargetTestUtils",
|
||||
],
|
||||
|
||||
@@ -25,11 +25,6 @@ cc_test {
|
||||
"android.hardware.sensors@2.X-shared-utils",
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.graphics.allocator@2.0",
|
||||
"android.hardware.graphics.allocator@3.0",
|
||||
"android.hardware.graphics.mapper@2.0",
|
||||
"android.hardware.graphics.mapper@2.1",
|
||||
"android.hardware.graphics.mapper@3.0",
|
||||
"android.hardware.sensors@1.0",
|
||||
"android.hardware.sensors@1.0-convert",
|
||||
"android.hardware.sensors@2.0",
|
||||
|
||||
@@ -27,11 +27,6 @@ cc_test {
|
||||
"android.hardware.sensors@2.X-shared-utils",
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.graphics.allocator@2.0",
|
||||
"android.hardware.graphics.allocator@3.0",
|
||||
"android.hardware.graphics.mapper@2.0",
|
||||
"android.hardware.graphics.mapper@2.1",
|
||||
"android.hardware.graphics.mapper@3.0",
|
||||
"android.hardware.sensors@1.0",
|
||||
"android.hardware.sensors@1.0-convert",
|
||||
"android.hardware.sensors@2.0",
|
||||
|
||||
@@ -29,11 +29,6 @@ cc_defaults {
|
||||
"libbinder",
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.graphics.allocator@2.0",
|
||||
"android.hardware.graphics.allocator@3.0",
|
||||
"android.hardware.graphics.mapper@2.0",
|
||||
"android.hardware.graphics.mapper@2.1",
|
||||
"android.hardware.graphics.mapper@3.0",
|
||||
"android.hardware.sensors@1.0",
|
||||
"android.hardware.sensors@1.0-convert",
|
||||
"android.hardware.sensors@2.0",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user