Merge "VTS: Fix IRadio.nvResetConfig" into rvc-dev
diff --git a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
index cde8048..368a6d4 100644
--- a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
+++ b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
@@ -38,16 +38,15 @@
#include <hidl/HidlTransportSupport.h>
#include <hwbinder/ProcessState.h>
-#include <log/log.h>
#include <utils/Errors.h>
#include <utils/StrongPointer.h>
-#include <android/log.h>
#include <android/hardware/automotive/evs/1.1/IEvsCamera.h>
#include <android/hardware/automotive/evs/1.1/IEvsCameraStream.h>
#include <android/hardware/automotive/evs/1.1/IEvsEnumerator.h>
#include <android/hardware/automotive/evs/1.1/IEvsDisplay.h>
#include <android/hardware/camera/device/3.2/ICameraDevice.h>
+#include <android-base/logging.h>
#include <system/camera_metadata.h>
#include <ui/DisplayConfig.h>
#include <ui/DisplayState.h>
@@ -98,18 +97,19 @@
std::string service_name = GetParam();
pEnumerator = IEvsEnumerator::getService(service_name);
ASSERT_NE(pEnumerator.get(), nullptr);
+ LOG(INFO) << "Test target service: " << service_name;
mIsHwModule = pEnumerator->isHardware();
}
virtual void TearDown() override {
// Attempt to close any active camera
- for (auto &&c : activeCameras) {
- sp<IEvsCamera_1_1> cam = c.promote();
+ for (auto &&cam : activeCameras) {
if (cam != nullptr) {
pEnumerator->closeCamera(cam);
}
}
+ activeCameras.clear();
}
protected:
@@ -120,11 +120,12 @@
// Get the camera list
pEnumerator->getCameraList_1_1(
[this](hidl_vec <CameraDesc> cameraList) {
- ALOGI("Camera list callback received %zu cameras",
- cameraList.size());
+ LOG(INFO) << "Camera list callback received "
+ << cameraList.size()
+ << " cameras";
cameraInfo.reserve(cameraList.size());
for (auto&& cam: cameraList) {
- ALOGI("Found camera %s", cam.v1.cameraId.c_str());
+ LOG(INFO) << "Found camera " << cam.v1.cameraId;
cameraInfo.push_back(cam);
}
}
@@ -137,10 +138,12 @@
// Get the ultrasonics array list
pEnumerator->getUltrasonicsArrayList([this](hidl_vec<UltrasonicsArrayDesc> ultraList) {
- ALOGI("Ultrasonics array list callback received %zu arrays", ultraList.size());
+ LOG(INFO) << "Ultrasonics array list callback received "
+ << ultraList.size()
+ << " arrays";
ultrasonicsArraysInfo.reserve(ultraList.size());
for (auto&& ultraArray : ultraList) {
- ALOGI("Found ultrasonics array %s", ultraArray.ultrasonicsArrayId.c_str());
+ LOG(INFO) << "Found ultrasonics array " << ultraArray.ultrasonicsArrayId;
ultrasonicsArraysInfo.push_back(ultraArray);
}
});
@@ -195,7 +198,7 @@
if (!flag) {
// EVS assumes that the device w/o a valid metadata is a physical
// device.
- ALOGI("%s is not a logical camera device.", id.c_str());
+ LOG(INFO) << id << " is not a logical camera device.";
physicalCameras.emplace(id);
return physicalCameras;
}
@@ -205,7 +208,9 @@
int rc = find_camera_metadata_ro_entry(metadata,
ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS,
&entry);
- ALOGE_IF(rc, "No physical camera ID is found for a logical camera device");
+ if (rc != 0) {
+ LOG(ERROR) << "No physical camera ID is found for a logical camera device";
+ }
const uint8_t *ids = entry.data.u8;
size_t start = 0;
@@ -219,7 +224,10 @@
}
}
- ALOGI("%s consists of %d physical camera devices.", id.c_str(), (int)physicalCameras.size());
+ LOG(INFO) << id
+ << " consists of "
+ << physicalCameras.size()
+ << " physical camera devices";
return physicalCameras;
}
@@ -228,7 +236,7 @@
std::vector<CameraDesc> cameraInfo; // Empty unless/until loadCameraList() is called
bool mIsHwModule; // boolean to tell current module under testing
// is HW module implementation.
- std::deque<wp<IEvsCamera_1_1>> activeCameras; // A list of active camera handles that are
+ std::deque<sp<IEvsCamera_1_1>> activeCameras; // A list of active camera handles that are
// needed to be cleaned up.
std::vector<UltrasonicsArrayDesc>
ultrasonicsArraysInfo; // Empty unless/until
@@ -247,7 +255,7 @@
* call to closeCamera. Then repeats the test to ensure all cameras can be reopened.
*/
TEST_P(EvsHidlTest, CameraOpenClean) {
- ALOGI("Starting CameraOpenClean test");
+ LOG(INFO) << "Starting CameraOpenClean test";
// Get the camera list
loadCameraList();
@@ -261,15 +269,12 @@
bool isLogicalCam = false;
auto devices = getPhysicalCameraIds(cam.v1.cameraId, isLogicalCam);
if (mIsHwModule && isLogicalCam) {
- ALOGI("Skip a logical device %s for HW module", cam.v1.cameraId.c_str());
+ LOG(INFO) << "Skip a logical device, " << cam.v1.cameraId << " for HW target.";
continue;
}
for (int pass = 0; pass < 2; pass++) {
- activeCameras.clear();
- sp<IEvsCamera_1_1> pCam =
- IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
- .withDefault(nullptr);
+ sp<IEvsCamera_1_1> pCam = pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg);
ASSERT_NE(pCam, nullptr);
for (auto&& devName : devices) {
@@ -286,7 +291,7 @@
// Verify that this camera self-identifies correctly
pCam->getCameraInfo_1_1([&cam](CameraDesc desc) {
- ALOGD("Found camera %s", desc.v1.cameraId.c_str());
+ LOG(DEBUG) << "Found camera " << desc.v1.cameraId;
EXPECT_EQ(cam.v1.cameraId, desc.v1.cameraId);
}
);
@@ -295,15 +300,16 @@
const auto id = 0xFFFFFFFF; // meaningless id
hidl_vec<uint8_t> values;
auto err = pCam->setExtendedInfo_1_1(id, values);
- ASSERT_EQ(EvsResult::INVALID_ARG, err);
+ ASSERT_NE(EvsResult::INVALID_ARG, err);
pCam->getExtendedInfo_1_1(id, [](const auto& result, const auto& data) {
- ASSERT_EQ(EvsResult::INVALID_ARG, result);
+ ASSERT_NE(EvsResult::INVALID_ARG, result);
ASSERT_EQ(0, data.size());
});
// Explicitly close the camera so resources are released right away
pEnumerator->closeCamera(pCam);
+ activeCameras.clear();
}
}
}
@@ -316,7 +322,7 @@
* the system to be tolerant of shutdown/restart race conditions.
*/
TEST_P(EvsHidlTest, CameraOpenAggressive) {
- ALOGI("Starting CameraOpenAggressive test");
+ LOG(INFO) << "Starting CameraOpenAggressive test";
// Get the camera list
loadCameraList();
@@ -330,7 +336,7 @@
bool isLogicalCam = false;
getPhysicalCameraIds(cam.v1.cameraId, isLogicalCam);
if (mIsHwModule && isLogicalCam) {
- ALOGI("Skip a logical device %s for HW module", cam.v1.cameraId.c_str());
+ LOG(INFO) << "Skip a logical device, " << cam.v1.cameraId << " for HW target.";
continue;
}
@@ -345,7 +351,7 @@
// Verify that this camera self-identifies correctly
pCam->getCameraInfo_1_1([&cam](CameraDesc desc) {
- ALOGD("Found camera %s", desc.v1.cameraId.c_str());
+ LOG(DEBUG) << "Found camera " << desc.v1.cameraId;
EXPECT_EQ(cam.v1.cameraId, desc.v1.cameraId);
}
);
@@ -371,16 +377,18 @@
// Close the superceded camera
pEnumerator->closeCamera(pCam);
+ activeCameras.pop_front();
// Verify that the second camera instance self-identifies correctly
pCam2->getCameraInfo_1_1([&cam](CameraDesc desc) {
- ALOGD("Found camera %s", desc.v1.cameraId.c_str());
+ LOG(DEBUG) << "Found camera " << desc.v1.cameraId;
EXPECT_EQ(cam.v1.cameraId, desc.v1.cameraId);
}
);
// Close the second camera instance
pEnumerator->closeCamera(pCam2);
+ activeCameras.pop_front();
}
// Sleep here to ensure the destructor cleanup has time to run so we don't break follow on tests
@@ -393,7 +401,7 @@
* Measure and qualify the stream start up time and streaming frame rate of each reported camera
*/
TEST_P(EvsHidlTest, CameraStreamPerformance) {
- ALOGI("Starting CameraStreamPerformance test");
+ LOG(INFO) << "Starting CameraStreamPerformance test";
// Get the camera list
loadCameraList();
@@ -407,11 +415,10 @@
bool isLogicalCam = false;
auto devices = getPhysicalCameraIds(cam.v1.cameraId, isLogicalCam);
if (mIsHwModule && isLogicalCam) {
- ALOGI("Skip a logical device %s", cam.v1.cameraId.c_str());
+ LOG(INFO) << "Skip a logical device " << cam.v1.cameraId;
continue;
}
- activeCameras.clear();
sp<IEvsCamera_1_1> pCam =
IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
.withDefault(nullptr);
@@ -444,8 +451,10 @@
kMaxStreamStartMilliseconds * devices.size());
printf("%s: Measured time to first frame %0.2f ms\n",
cam.v1.cameraId.c_str(), timeToFirstFrame * kNanoToMilliseconds);
- ALOGI("%s: Measured time to first frame %0.2f ms",
- cam.v1.cameraId.c_str(), timeToFirstFrame * kNanoToMilliseconds);
+ LOG(INFO) << cam.v1.cameraId
+ << ": Measured time to first frame "
+ << std::scientific << timeToFirstFrame * kNanoToMilliseconds
+ << " ms.";
// Check aspect ratio
unsigned width = 0, height = 0;
@@ -468,11 +477,14 @@
nsecs_t runTime = end - firstFrame;
float framesPerSecond = framesReceived / (runTime * kNanoToSeconds);
printf("Measured camera rate %3.2f fps\n", framesPerSecond);
- ALOGI("Measured camera rate %3.2f fps", framesPerSecond);
+ LOG(INFO) << "Measured camera rate "
+ << std::scientific << framesPerSecond
+ << " fps.";
EXPECT_GE(framesPerSecond, kMinimumFramesPerSecond);
// Explicitly release the camera
pEnumerator->closeCamera(pCam);
+ activeCameras.clear();
}
}
@@ -483,7 +495,7 @@
* than one frame time. The camera must cleanly skip frames until the client is ready again.
*/
TEST_P(EvsHidlTest, CameraStreamBuffering) {
- ALOGI("Starting CameraStreamBuffering test");
+ LOG(INFO) << "Starting CameraStreamBuffering test";
// Arbitrary constant (should be > 1 and less than crazy)
static const unsigned int kBuffersToHold = 6;
@@ -500,11 +512,10 @@
bool isLogicalCam = false;
getPhysicalCameraIds(cam.v1.cameraId, isLogicalCam);
if (mIsHwModule && isLogicalCam) {
- ALOGI("Skip a logical device %s for HW module", cam.v1.cameraId.c_str());
+ LOG(INFO) << "Skip a logical device " << cam.v1.cameraId << " for HW target.";
continue;
}
- activeCameras.clear();
sp<IEvsCamera_1_1> pCam =
IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
.withDefault(nullptr);
@@ -557,6 +568,7 @@
// Explicitly release the camera
pEnumerator->closeCamera(pCam);
+ activeCameras.clear();
}
}
@@ -568,7 +580,7 @@
* which a human could observe to see the operation of the system on the physical display.
*/
TEST_P(EvsHidlTest, CameraToDisplayRoundTrip) {
- ALOGI("Starting CameraToDisplayRoundTrip test");
+ LOG(INFO) << "Starting CameraToDisplayRoundTrip test";
// Get the camera list
loadCameraList();
@@ -587,14 +599,14 @@
// Request exclusive access to the first EVS display
sp<IEvsDisplay_1_1> pDisplay = pEnumerator->openDisplay_1_1(targetDisplayId);
ASSERT_NE(pDisplay, nullptr);
- ALOGI("Display %d is in use.", targetDisplayId);
+ LOG(INFO) << "Display " << targetDisplayId << " is alreay in use.";
// Get the display descriptor
pDisplay->getDisplayInfo_1_1([](const auto& config, const auto& state) {
android::DisplayConfig* pConfig = (android::DisplayConfig*)config.data();
const auto width = pConfig->resolution.getWidth();
const auto height = pConfig->resolution.getHeight();
- ALOGI(" Resolution: %dx%d", width, height);
+ LOG(INFO) << " Resolution: " << width << "x" << height;
ASSERT_GT(width, 0);
ASSERT_GT(height, 0);
@@ -607,11 +619,10 @@
bool isLogicalCam = false;
getPhysicalCameraIds(cam.v1.cameraId, isLogicalCam);
if (mIsHwModule && isLogicalCam) {
- ALOGI("Skip a logical device %s for HW module", cam.v1.cameraId.c_str());
+ LOG(INFO) << "Skip a logical device " << cam.v1.cameraId << " for HW target.";
continue;
}
- activeCameras.clear();
sp<IEvsCamera_1_1> pCam =
IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
.withDefault(nullptr);
@@ -654,6 +665,7 @@
// Explicitly release the camera
pEnumerator->closeCamera(pCam);
+ activeCameras.clear();
}
// Explicitly release the display
@@ -667,7 +679,7 @@
* underlying camera.
*/
TEST_P(EvsHidlTest, MultiCameraStream) {
- ALOGI("Starting MultiCameraStream test");
+ LOG(INFO) << "Starting MultiCameraStream test";
if (mIsHwModule) {
// This test is not for HW module implementation.
@@ -683,7 +695,6 @@
// Test each reported camera
for (auto&& cam: cameraInfo) {
- activeCameras.clear();
// Create two camera clients.
sp<IEvsCamera_1_1> pCam0 =
IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
@@ -735,7 +746,9 @@
nsecs_t runTime = end - firstFrame;
float framesPerSecond0 = framesReceived0 / (runTime * kNanoToSeconds);
float framesPerSecond1 = framesReceived1 / (runTime * kNanoToSeconds);
- ALOGI("Measured camera rate %3.2f fps and %3.2f fps", framesPerSecond0, framesPerSecond1);
+ LOG(INFO) << "Measured camera rate "
+ << std::scientific << framesPerSecond0 << " fps and "
+ << framesPerSecond1 << " fps";
EXPECT_GE(framesPerSecond0, kMinimumFramesPerSecond);
EXPECT_GE(framesPerSecond1, kMinimumFramesPerSecond);
@@ -760,6 +773,7 @@
// Explicitly release the camera
pEnumerator->closeCamera(pCam0);
pEnumerator->closeCamera(pCam1);
+ activeCameras.clear();
// TODO(b/145459970, b/145457727): below sleep() is added to ensure the
// destruction of active camera objects; this may be related with two
@@ -774,7 +788,7 @@
* Verify that a client can adjust a camera parameter.
*/
TEST_P(EvsHidlTest, CameraParameter) {
- ALOGI("Starting CameraParameter test");
+ LOG(INFO) << "Starting CameraParameter test";
// Get the camera list
loadCameraList();
@@ -791,11 +805,10 @@
if (isLogicalCam) {
// TODO(b/145465724): Support camera parameter programming on
// logical devices.
- ALOGI("Skip a logical device %s", cam.v1.cameraId.c_str());
+ LOG(INFO) << "Skip a logical device " << cam.v1.cameraId;
continue;
}
- activeCameras.clear();
// Create a camera client
sp<IEvsCamera_1_1> pCam =
IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
@@ -908,6 +921,7 @@
// Explicitly release the camera
pEnumerator->closeCamera(pCam);
+ activeCameras.clear();
}
}
@@ -918,7 +932,7 @@
* terminates or releases a role.
*/
TEST_P(EvsHidlTest, CameraMasterRelease) {
- ALOGI("Starting CameraMasterRelease test");
+ LOG(INFO) << "Starting CameraMasterRelease test";
if (mIsHwModule) {
// This test is not for HW module implementation.
@@ -939,11 +953,10 @@
if (isLogicalCam) {
// TODO(b/145465724): Support camera parameter programming on
// logical devices.
- ALOGI("Skip a logical device %s", cam.v1.cameraId.c_str());
+ LOG(INFO) << "Skip a logical device " << cam.v1.cameraId;
continue;
}
- activeCameras.clear();
// Create two camera clients.
sp<IEvsCamera_1_1> pCamMaster =
IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
@@ -1012,7 +1025,7 @@
EvsEventDesc aTargetEvent;
aTargetEvent.aType = EvsEventType::MASTER_RELEASED;
if (!frameHandlerNonMaster->waitForEvent(aTargetEvent, aNotification, true)) {
- ALOGW("A timer is expired before a target event is fired.");
+ LOG(WARNING) << "A timer is expired before a target event is fired.";
}
}
@@ -1057,7 +1070,7 @@
EvsEventDesc aTargetEvent;
aTargetEvent.aType = EvsEventType::MASTER_RELEASED;
if (!frameHandlerMaster->waitForEvent(aTargetEvent, aNotification, true)) {
- ALOGW("A timer is expired before a target event is fired.");
+ LOG(WARNING) << "A timer is expired before a target event is fired.";
}
}
@@ -1089,6 +1102,7 @@
// Explicitly release the camera
pEnumerator->closeCamera(pCamMaster);
pEnumerator->closeCamera(pCamNonMaster);
+ activeCameras.clear();
}
}
@@ -1099,7 +1113,7 @@
* camera parameters.
*/
TEST_P(EvsHidlTest, MultiCameraParameter) {
- ALOGI("Starting MultiCameraParameter test");
+ LOG(INFO) << "Starting MultiCameraParameter test";
if (mIsHwModule) {
// This test is not for HW module implementation.
@@ -1120,11 +1134,10 @@
if (isLogicalCam) {
// TODO(b/145465724): Support camera parameter programming on
// logical devices.
- ALOGI("Skip a logical device %s", cam.v1.cameraId.c_str());
+ LOG(INFO) << "Skip a logical device " << cam.v1.cameraId;
continue;
}
- activeCameras.clear();
// Create two camera clients.
sp<IEvsCamera_1_1> pCamMaster =
IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
@@ -1256,7 +1269,7 @@
aTargetEvent.payload[0] = static_cast<uint32_t>(cmd);
aTargetEvent.payload[1] = val0;
if (!frameHandlerMaster->waitForEvent(aTargetEvent, aNotification0)) {
- ALOGW("A timer is expired before a target event is fired.");
+ LOG(WARNING) << "A timer is expired before a target event is fired.";
}
}
);
@@ -1273,7 +1286,7 @@
aTargetEvent.payload[0] = static_cast<uint32_t>(cmd);
aTargetEvent.payload[1] = val0;
if (!frameHandlerNonMaster->waitForEvent(aTargetEvent, aNotification1)) {
- ALOGW("A timer is expired before a target event is fired.");
+ LOG(WARNING) << "A timer is expired before a target event is fired.";
}
}
);
@@ -1374,7 +1387,7 @@
EvsEventDesc aTargetEvent;
aTargetEvent.aType = EvsEventType::MASTER_RELEASED;
if (!frameHandlerNonMaster->waitForEvent(aTargetEvent, aNotification0, true)) {
- ALOGW("A timer is expired before a target event is fired.");
+ LOG(WARNING) << "A timer is expired before a target event is fired.";
}
}
);
@@ -1466,7 +1479,7 @@
aTargetEvent.payload[0] = static_cast<uint32_t>(cmd);
aTargetEvent.payload[1] = val0;
if (!frameHandlerMaster->waitForEvent(aTargetEvent, aNotification0)) {
- ALOGW("A timer is expired before a target event is fired.");
+ LOG(WARNING) << "A timer is expired before a target event is fired.";
}
}
);
@@ -1482,7 +1495,7 @@
aTargetEvent.payload[0] = static_cast<uint32_t>(cmd);
aTargetEvent.payload[1] = val0;
if (!frameHandlerNonMaster->waitForEvent(aTargetEvent, aNotification1)) {
- ALOGW("A timer is expired before a target event is fired.");
+ LOG(WARNING) << "A timer is expired before a target event is fired.";
}
}
);
@@ -1562,6 +1575,7 @@
// Explicitly release the camera
pEnumerator->closeCamera(pCamMaster);
pEnumerator->closeCamera(pCamNonMaster);
+ activeCameras.clear();
}
}
@@ -1572,7 +1586,7 @@
* a master role from other EVS clients without the display.
*/
TEST_P(EvsHidlTest, HighPriorityCameraClient) {
- ALOGI("Starting HighPriorityCameraClient test");
+ LOG(INFO) << "Starting HighPriorityCameraClient test";
if (mIsHwModule) {
// This test is not for HW module implementation.
@@ -1592,8 +1606,6 @@
// Test each reported camera
for (auto&& cam: cameraInfo) {
- activeCameras.clear();
-
// Create two clients
sp<IEvsCamera_1_1> pCam0 =
IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
@@ -1687,7 +1699,7 @@
aTargetEvent.payload[0] = static_cast<uint32_t>(CameraParam::AUTO_FOCUS);
aTargetEvent.payload[1] = 0;
if (!frameHandler0->waitForEvent(aTargetEvent, aNotification)) {
- ALOGW("A timer is expired before a target event is fired.");
+ LOG(WARNING) << "A timer is expired before a target event is fired.";
}
}
);
@@ -1740,7 +1752,7 @@
aTargetEvent.payload[0] = static_cast<uint32_t>(cam1Cmds[0]);
aTargetEvent.payload[1] = val0;
if (!frameHandler1->waitForEvent(aTargetEvent, aNotification)) {
- ALOGW("A timer is expired before a target event is fired.");
+ LOG(WARNING) << "A timer is expired before a target event is fired.";
}
}
);
@@ -1791,7 +1803,7 @@
EvsEventDesc aTargetEvent;
aTargetEvent.aType = EvsEventType::MASTER_RELEASED;
if (!frameHandler1->waitForEvent(aTargetEvent, aNotification, true)) {
- ALOGW("A timer is expired before a target event is fired.");
+ LOG(WARNING) << "A timer is expired before a target event is fired.";
}
}
);
@@ -1833,7 +1845,7 @@
aTargetEvent.payload[0] = static_cast<uint32_t>(CameraParam::AUTO_FOCUS);
aTargetEvent.payload[1] = 0;
if (!frameHandler1->waitForEvent(aTargetEvent, aNotification)) {
- ALOGW("A timer is expired before a target event is fired.");
+ LOG(WARNING) << "A timer is expired before a target event is fired.";
}
}
);
@@ -1882,7 +1894,7 @@
aTargetEvent.payload[0] = static_cast<uint32_t>(cam0Cmds[0]);
aTargetEvent.payload[1] = val0;
if (!frameHandler0->waitForEvent(aTargetEvent, aNotification)) {
- ALOGW("A timer is expired before a target event is fired.");
+ LOG(WARNING) << "A timer is expired before a target event is fired.";
}
}
);
@@ -1931,6 +1943,8 @@
// Explicitly release the camera
pEnumerator->closeCamera(pCam0);
pEnumerator->closeCamera(pCam1);
+ activeCameras.clear();
+
}
// Explicitly release the display
@@ -1945,7 +1959,7 @@
* configurations from EVS and uses one of them to start a video stream.
*/
TEST_P(EvsHidlTest, CameraUseStreamConfigToDisplay) {
- ALOGI("Starting CameraUseStreamConfigToDisplay test");
+ LOG(INFO) << "Starting CameraUseStreamConfigToDisplay test";
// Get the camera list
loadCameraList();
@@ -1956,7 +1970,6 @@
// Test each reported camera
for (auto&& cam: cameraInfo) {
- activeCameras.clear();
// choose a configuration that has a frame rate faster than minReqFps.
Stream targetCfg = {};
const int32_t minReqFps = 15;
@@ -2036,6 +2049,7 @@
// Explicitly release the camera
pEnumerator->closeCamera(pCam);
+ activeCameras.clear();
}
// Explicitly release the display
@@ -2049,7 +2063,7 @@
* underlying camera with same configuration.
*/
TEST_P(EvsHidlTest, MultiCameraStreamUseConfig) {
- ALOGI("Starting MultiCameraStream test");
+ LOG(INFO) << "Starting MultiCameraStream test";
if (mIsHwModule) {
// This test is not for HW module implementation.
@@ -2061,7 +2075,6 @@
// Test each reported camera
for (auto&& cam: cameraInfo) {
- activeCameras.clear();
// choose a configuration that has a frame rate faster than minReqFps.
Stream targetCfg = {};
const int32_t minReqFps = 15;
@@ -2094,9 +2107,8 @@
static_cast<PixelFormat>(HAL_PIXEL_FORMAT_RGBA_8888);
if (!foundCfg) {
- ALOGI("Device %s does not provide a list of supported stream configurations, skipped",
- cam.v1.cameraId.c_str());
-
+ LOG(INFO) << "Device " << cam.v1.cameraId
+ << " does not provide a list of supported stream configurations, skipped";
continue;
}
@@ -2162,7 +2174,9 @@
nsecs_t runTime = end - firstFrame;
float framesPerSecond0 = framesReceived0 / (runTime * kNanoToSeconds);
float framesPerSecond1 = framesReceived1 / (runTime * kNanoToSeconds);
- ALOGI("Measured camera rate %3.2f fps and %3.2f fps", framesPerSecond0, framesPerSecond1);
+ LOG(INFO) << "Measured camera rate "
+ << std::scientific << framesPerSecond0 << " fps and "
+ << framesPerSecond1 << " fps";
EXPECT_GE(framesPerSecond0, kMinimumFramesPerSecond);
EXPECT_GE(framesPerSecond1, kMinimumFramesPerSecond);
@@ -2187,6 +2201,7 @@
// Explicitly release the camera
pEnumerator->closeCamera(pCam0);
pEnumerator->closeCamera(pCam1);
+ activeCameras.clear();
}
}
@@ -2198,7 +2213,7 @@
* identifiers.
*/
TEST_P(EvsHidlTest, LogicalCameraMetadata) {
- ALOGI("Starting LogicalCameraMetadata test");
+ LOG(INFO) << "Starting LogicalCameraMetadata test";
// Get the camera list
loadCameraList();
@@ -2222,7 +2237,7 @@
* can be reopened.
*/
TEST_P(EvsHidlTest, UltrasonicsArrayOpenClean) {
- ALOGI("Starting UltrasonicsArrayOpenClean test");
+ LOG(INFO) << "Starting UltrasonicsArrayOpenClean test";
// Get the ultrasonics array list
loadUltrasonicsArrayList();
@@ -2236,7 +2251,7 @@
// Verify that this ultrasonics array self-identifies correctly
pUltrasonicsArray->getUltrasonicArrayInfo([&ultraInfo](UltrasonicsArrayDesc desc) {
- ALOGD("Found ultrasonics array %s", ultraInfo.ultrasonicsArrayId.c_str());
+ LOG(DEBUG) << "Found ultrasonics array " << ultraInfo.ultrasonicsArrayId;
EXPECT_EQ(ultraInfo.ultrasonicsArrayId, desc.ultrasonicsArrayId);
});
@@ -2249,14 +2264,14 @@
// Starts a stream and verifies all data received is valid.
TEST_P(EvsHidlTest, UltrasonicsVerifyStreamData) {
- ALOGI("Starting UltrasonicsVerifyStreamData");
+ LOG(INFO) << "Starting UltrasonicsVerifyStreamData";
// Get the ultrasonics array list
loadUltrasonicsArrayList();
// For each ultrasonics array.
for (auto&& ultraInfo : ultrasonicsArraysInfo) {
- ALOGD("Testing ultrasonics array: %s", ultraInfo.ultrasonicsArrayId.c_str());
+ LOG(DEBUG) << "Testing ultrasonics array: " << ultraInfo.ultrasonicsArrayId;
sp<IEvsUltrasonicsArray> pUltrasonicsArray =
pEnumerator->openUltrasonicsArray(ultraInfo.ultrasonicsArrayId);
@@ -2285,14 +2300,14 @@
// Sets frames in flight before and after start of stream and verfies success.
TEST_P(EvsHidlTest, UltrasonicsSetFramesInFlight) {
- ALOGI("Starting UltrasonicsSetFramesInFlight");
+ LOG(INFO) << "Starting UltrasonicsSetFramesInFlight";
// Get the ultrasonics array list
loadUltrasonicsArrayList();
// For each ultrasonics array.
for (auto&& ultraInfo : ultrasonicsArraysInfo) {
- ALOGD("Testing ultrasonics array: %s", ultraInfo.ultrasonicsArrayId.c_str());
+ LOG(DEBUG) << "Testing ultrasonics array: " << ultraInfo.ultrasonicsArrayId;
sp<IEvsUltrasonicsArray> pUltrasonicsArray =
pEnumerator->openUltrasonicsArray(ultraInfo.ultrasonicsArrayId);
diff --git a/bluetooth/1.1/IBluetoothHci.hal b/bluetooth/1.1/IBluetoothHci.hal
index 0f69c6e..2a520c1 100644
--- a/bluetooth/1.1/IBluetoothHci.hal
+++ b/bluetooth/1.1/IBluetoothHci.hal
@@ -35,8 +35,8 @@
initialize_1_1(@1.1::IBluetoothHciCallbacks callback);
/**
- * Send an ISO data packet (as specified in the Bluetooth Specification
- * V6.0) to the Bluetooth controller.
+ * Send an ISO data packet (as specified in the Bluetooth Core
+ * Specification v5.2) to the Bluetooth controller.
* Packets must be processed in order.
* @param data HCI data packet to be sent
*/
diff --git a/current.txt b/current.txt
index a6f35ba..873e2f6 100644
--- a/current.txt
+++ b/current.txt
@@ -589,6 +589,7 @@
a05277065c28ebecd58118bd240fb8c55757361e8648c01f7c4dacdb7f2a95dc android.hardware.camera.metadata@3.3::types
9cb3df2bde2c6cd5fd96b7c41555420cacd7e276a556c684af91b7461c86460f android.hardware.gnss@1.0::IGnssCallback
af334f1fc85c62b343f84b74d0495eed6f495f7fecedb53463db10c202310058 android.hardware.gnss.measurement_corrections@1.0::types
+33a6b20c43af00fdfb305df891bc5911c06d9a9130b912759649932e5a4a6e6d android.hardware.gnss.visibility_control@1.0::IGnssVisibilityControlCallback
bceee81ec1b59324abd05932b5620fda5a6589597c9cb3953ba7f3ea02cccd3e android.hardware.camera.provider@2.4::ICameraProvider
2ce820dc4f3c6d85721b65150ed2157c6e2e2055f866fb6c6ba4790f14408d66 android.hardware.camera.provider@2.4::ICameraProviderCallback
b69a7615c508acf5c5201efd1bfa3262167874fc3594e2db5a3ff93addd8ac75 android.hardware.keymaster@4.0::IKeymasterDevice
@@ -634,7 +635,7 @@
ae6315fd42196478ac08441cb489d854118001bca5b9b9fd58af5110952be30e android.hardware.biometrics.fingerprint@2.2::types
6828bbf18dc5d0f00c73341a10c8e4d574346c1abb1c2ed682ba5e9f8a3240d9 android.hardware.biometrics.fingerprint@2.2::IBiometricsFingerprint
82cad99f5feb2ea9bcd4579055edf4af8feb9fc602a6e4827ddd727d254d4991 android.hardware.biometrics.fingerprint@2.2::IBiometricsFingerprintClientCallback
-79e115c8f8970b8b914bafc66df5425e065fda4dcda97222966ef12451d2a1cc android.hardware.bluetooth@1.1::IBluetoothHci
+362fd1c21641c2224f3b80c30d9797b988fa3f344243d531ba73c553779a5763 android.hardware.bluetooth@1.1::IBluetoothHci
40ab2c6866c18d32baf6e49e3053949e79601f56963a791e93e68b9ee18f718d android.hardware.bluetooth@1.1::IBluetoothHciCallbacks
07d0a252b2d8fa35887908a996ba395cf392968395fc30afab791f46e0c22a52 android.hardware.boot@1.1::IBootControl
74049a402be913963edfdd80828a53736570e9d8124a1bf18166b6ed46a6b0ab android.hardware.boot@1.1::types
diff --git a/gnss/visibility_control/1.0/IGnssVisibilityControlCallback.hal b/gnss/visibility_control/1.0/IGnssVisibilityControlCallback.hal
index 5a582c2..5ee2923 100644
--- a/gnss/visibility_control/1.0/IGnssVisibilityControlCallback.hal
+++ b/gnss/visibility_control/1.0/IGnssVisibilityControlCallback.hal
@@ -82,6 +82,9 @@
/**
* Package name of the Android proxy application representing the non-framework
* entity that requested location. Set to empty string if unknown.
+ *
+ * For user-initiated emergency use cases, this field must be set to empty string
+ * and the inEmergencyMode field must be set to true.
*/
string proxyAppPackageName;
@@ -157,4 +160,4 @@
* @return success True if the framework determines that the device is in emergency session.
*/
isInEmergencySession() generates (bool success);
-};
\ No newline at end of file
+};
diff --git a/graphics/common/aidl/android/hardware/graphics/common/PlaneLayoutComponent.aidl b/graphics/common/aidl/android/hardware/graphics/common/PlaneLayoutComponent.aidl
index 3fca53b..c04cef0 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/PlaneLayoutComponent.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/PlaneLayoutComponent.aidl
@@ -39,7 +39,7 @@
/**
* The type of this plane layout component.
*
- * android.hardware.graphics.common.PlaneLayoutComponent defines the standard
+ * android.hardware.graphics.common.PlaneLayoutComponentType defines the standard
* plane layout component types. Vendors may extend this type to include any
* non-standard plane layout component types. For instructions on how to
* create a vendor extension, refer to ExtendableType.aidl.
diff --git a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
index 10ce4c2..cc14271 100644
--- a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
+++ b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
@@ -176,6 +176,10 @@
* @param itemsRequest
* If non-empty, contains request data that is signed by the reader. See above.
*
+ * @param signingKeyBlob is either empty or a signingKeyBlob (see generateSigningKeyPair(),
+ * below) containing the signing key to use to sign the data retrieved. If this
+ * is not in the right format the call fails with STATUS_INVALID_DATA.
+ *
* @param sessionTranscript
* Either empty or the CBOR of the SessionTranscript. See above.
*
@@ -195,8 +199,7 @@
* and remove the corresponding requests from the counts.
*/
void startRetrieval(in SecureAccessControlProfile[] accessControlProfiles,
- in HardwareAuthToken authToken,
- in byte[] itemsRequest,
+ in HardwareAuthToken authToken, in byte[] itemsRequest, in byte[] signingKeyBlob,
in byte[] sessionTranscript, in byte[] readerSignature, in int[] requestCounts);
/**
@@ -254,10 +257,6 @@
* If signingKeyBlob or the sessionTranscript parameter passed to startRetrieval() is
* empty then the returned MAC will be empty.
*
- * @param signingKeyBlob is either empty or a signingKeyBlob (see generateSigningKeyPair(),
- * below) containing the signing key to use to sign the data retrieved. If this
- * is not in the right format the call fails with STATUS_INVALID_DATA.
- *
* @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.
@@ -304,7 +303,7 @@
*
* @param out deviceNameSpaces the bytes of DeviceNameSpaces.
*/
- void finishRetrieval(in byte[] signingKeyBlob, out byte[] mac, out byte[] deviceNameSpaces);
+ void finishRetrieval(out byte[] mac, out byte[] deviceNameSpaces);
/**
* Generate a key pair to be used for signing session data and retrieved data items.
diff --git a/identity/aidl/default/IdentityCredential.cpp b/identity/aidl/default/IdentityCredential.cpp
index d5b3a0f..341fae6 100644
--- a/identity/aidl/default/IdentityCredential.cpp
+++ b/identity/aidl/default/IdentityCredential.cpp
@@ -256,8 +256,8 @@
ndk::ScopedAStatus IdentityCredential::startRetrieval(
const vector<SecureAccessControlProfile>& accessControlProfiles,
const HardwareAuthToken& authToken, const vector<int8_t>& itemsRequestS,
- const vector<int8_t>& sessionTranscriptS, const vector<int8_t>& readerSignatureS,
- const vector<int32_t>& requestCounts) {
+ const vector<int8_t>& signingKeyBlobS, const vector<int8_t>& sessionTranscriptS,
+ const vector<int8_t>& readerSignatureS, const vector<int32_t>& requestCounts) {
auto sessionTranscript = byteStringToUnsigned(sessionTranscriptS);
auto itemsRequest = byteStringToUnsigned(itemsRequestS);
auto readerSignature = byteStringToUnsigned(readerSignatureS);
@@ -498,6 +498,7 @@
currentNameSpace_ = "";
itemsRequest_ = itemsRequest;
+ signingKeyBlob_ = byteStringToUnsigned(signingKeyBlobS);
numStartRetrievalCalls_ += 1;
return ndk::ScopedAStatus::ok();
@@ -650,11 +651,8 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus IdentityCredential::finishRetrieval(const vector<int8_t>& signingKeyBlobS,
- vector<int8_t>* outMac,
+ndk::ScopedAStatus IdentityCredential::finishRetrieval(vector<int8_t>* outMac,
vector<int8_t>* outDeviceNameSpaces) {
- auto signingKeyBlob = byteStringToUnsigned(signingKeyBlobS);
-
if (currentNameSpaceDeviceNameSpacesMap_.size() > 0) {
deviceNameSpacesMap_.add(currentNameSpace_,
std::move(currentNameSpaceDeviceNameSpacesMap_));
@@ -664,7 +662,8 @@
// If there's no signing key or no sessionTranscript or no reader ephemeral
// public key, we return the empty MAC.
optional<vector<uint8_t>> mac;
- if (signingKeyBlob.size() > 0 && sessionTranscript_.size() > 0 && readerPublicKey_.size() > 0) {
+ if (signingKeyBlob_.size() > 0 && sessionTranscript_.size() > 0 &&
+ readerPublicKey_.size() > 0) {
cppbor::Array array;
array.add("DeviceAuthentication");
array.add(sessionTranscriptItem_->clone());
@@ -674,7 +673,7 @@
vector<uint8_t> docTypeAsBlob(docType_.begin(), docType_.end());
optional<vector<uint8_t>> signingKey =
- support::decryptAes128Gcm(storageKey_, signingKeyBlob, docTypeAsBlob);
+ support::decryptAes128Gcm(storageKey_, signingKeyBlob_, docTypeAsBlob);
if (!signingKey) {
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
IIdentityCredentialStore::STATUS_INVALID_DATA,
diff --git a/identity/aidl/default/IdentityCredential.h b/identity/aidl/default/IdentityCredential.h
index 49ed0d4..fc29254 100644
--- a/identity/aidl/default/IdentityCredential.h
+++ b/identity/aidl/default/IdentityCredential.h
@@ -54,14 +54,14 @@
ndk::ScopedAStatus startRetrieval(
const vector<SecureAccessControlProfile>& accessControlProfiles,
const HardwareAuthToken& authToken, const vector<int8_t>& itemsRequest,
- const vector<int8_t>& sessionTranscript, const vector<int8_t>& readerSignature,
- const vector<int32_t>& requestCounts) override;
+ const vector<int8_t>& signingKeyBlob, const vector<int8_t>& sessionTranscript,
+ const vector<int8_t>& readerSignature, const vector<int32_t>& requestCounts) override;
ndk::ScopedAStatus startRetrieveEntryValue(
const string& nameSpace, const string& name, int32_t entrySize,
const vector<int32_t>& accessControlProfileIds) override;
ndk::ScopedAStatus retrieveEntryValue(const vector<int8_t>& encryptedContent,
vector<int8_t>* outContent) override;
- ndk::ScopedAStatus finishRetrieval(const vector<int8_t>& signingKeyBlob, vector<int8_t>* outMac,
+ ndk::ScopedAStatus finishRetrieval(vector<int8_t>* outMac,
vector<int8_t>* outDeviceNameSpaces) override;
ndk::ScopedAStatus generateSigningKeyPair(vector<int8_t>* outSigningKeyBlob,
Certificate* outSigningKeyCertificate) override;
@@ -88,6 +88,7 @@
// Set at startRetrieval() time.
map<int32_t, int> profileIdToAccessCheckResult_;
+ vector<uint8_t> signingKeyBlob_;
vector<uint8_t> sessionTranscript_;
std::unique_ptr<cppbor::Item> sessionTranscriptItem_;
vector<uint8_t> itemsRequest_;
diff --git a/identity/aidl/default/WritableIdentityCredential.cpp b/identity/aidl/default/WritableIdentityCredential.cpp
index ba2062d..89f7f35 100644
--- a/identity/aidl/default/WritableIdentityCredential.cpp
+++ b/identity/aidl/default/WritableIdentityCredential.cpp
@@ -16,6 +16,9 @@
#define LOG_TAG "WritableIdentityCredential"
+#include "WritableIdentityCredential.h"
+#include "IdentityCredentialStore.h"
+
#include <android/hardware/identity/support/IdentityCredentialSupport.h>
#include <android-base/logging.h>
@@ -23,6 +26,8 @@
#include <cppbor/cppbor.h>
#include <cppbor/cppbor_parse.h>
+#include <utility>
+
#include "IdentityCredentialStore.h"
#include "Util.h"
#include "WritableIdentityCredential.h"
@@ -33,26 +38,6 @@
using namespace ::android::hardware::identity;
bool WritableIdentityCredential::initialize() {
- optional<vector<uint8_t>> keyPair = support::createEcKeyPair();
- if (!keyPair) {
- LOG(ERROR) << "Error creating credentialKey";
- return false;
- }
-
- optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair.value());
- if (!pubKey) {
- LOG(ERROR) << "Error getting public part of credentialKey";
- return false;
- }
- credentialPubKey_ = pubKey.value();
-
- optional<vector<uint8_t>> privKey = support::ecKeyPairGetPrivateKey(keyPair.value());
- if (!privKey) {
- LOG(ERROR) << "Error getting private part of credentialKey";
- return false;
- }
- credentialPrivKey_ = privKey.value();
-
optional<vector<uint8_t>> random = support::getRandom(16);
if (!random) {
LOG(ERROR) << "Error creating storageKey";
@@ -63,88 +48,54 @@
return true;
}
-// TODO: use |attestationApplicationId| and |attestationChallenge| and also
-// ensure the returned certificate chain satisfy the requirements listed in
-// the docs for IWritableIdentityCredential::getAttestationCertificate()
-//
+// This function generates the attestation certificate using the passed in
+// |attestationApplicationId| and |attestationChallenge|. It will generate an
+// attestation certificate with current time and expires one year from now. The
+// certificate shall contain all values as specified in hal.
ndk::ScopedAStatus WritableIdentityCredential::getAttestationCertificate(
- const vector<int8_t>& /*attestationApplicationId*/,
- const vector<int8_t>& /*attestationChallenge*/, vector<Certificate>* outCertificateChain) {
- // For now, we dynamically generate an attestion key on each and every
- // request and use that to sign CredentialKey. In a real implementation this
- // would look very differently.
- optional<vector<uint8_t>> attestationKeyPair = support::createEcKeyPair();
- if (!attestationKeyPair) {
- return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
- IIdentityCredentialStore::STATUS_FAILED, "Error creating attestationKey"));
- }
-
- optional<vector<uint8_t>> attestationPubKey =
- support::ecKeyPairGetPublicKey(attestationKeyPair.value());
- if (!attestationPubKey) {
+ const vector<int8_t>& attestationApplicationId, //
+ const vector<int8_t>& attestationChallenge, //
+ vector<Certificate>* outCertificateChain) {
+ if (!credentialPrivKey_.empty() || !credentialPubKey_.empty() || !certificateChain_.empty()) {
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
IIdentityCredentialStore::STATUS_FAILED,
- "Error getting public part of attestationKey"));
+ "Error attestation certificate previously generated"));
}
- optional<vector<uint8_t>> attestationPrivKey =
- support::ecKeyPairGetPrivateKey(attestationKeyPair.value());
- if (!attestationPrivKey) {
+ vector<uint8_t> challenge(attestationChallenge.begin(), attestationChallenge.end());
+ vector<uint8_t> appId(attestationApplicationId.begin(), attestationApplicationId.end());
+
+ optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> keyAttestationPair =
+ support::createEcKeyPairAndAttestation(challenge, appId);
+ if (!keyAttestationPair) {
+ LOG(ERROR) << "Error creating credentialKey and attestation";
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
IIdentityCredentialStore::STATUS_FAILED,
- "Error getting private part of attestationKey"));
+ "Error creating credentialKey and attestation"));
}
- string serialDecimal;
- string issuer;
- string subject;
- time_t validityNotBefore = time(nullptr);
- time_t validityNotAfter = validityNotBefore + 365 * 24 * 3600;
+ vector<uint8_t> keyPair = keyAttestationPair.value().first;
+ certificateChain_ = keyAttestationPair.value().second;
- // First create a certificate for |credentialPubKey| which is signed by
- // |attestationPrivKey|.
- //
- serialDecimal = "0"; // TODO: set serial to |attestationChallenge|
- issuer = "Android Open Source Project";
- subject = "Android IdentityCredential CredentialKey";
- optional<vector<uint8_t>> credentialPubKeyCertificate = support::ecPublicKeyGenerateCertificate(
- credentialPubKey_, attestationPrivKey.value(), serialDecimal, issuer, subject,
- validityNotBefore, validityNotAfter);
- if (!credentialPubKeyCertificate) {
+ optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair);
+ if (!pubKey) {
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
IIdentityCredentialStore::STATUS_FAILED,
- "Error creating certificate for credentialPubKey"));
+ "Error getting public part of credentialKey"));
}
+ credentialPubKey_ = pubKey.value();
- // This is followed by a certificate for |attestationPubKey| self-signed by
- // |attestationPrivKey|.
- serialDecimal = "0"; // TODO: set serial
- issuer = "Android Open Source Project";
- subject = "Android IdentityCredential AttestationKey";
- optional<vector<uint8_t>> attestationKeyCertificate = support::ecPublicKeyGenerateCertificate(
- attestationPubKey.value(), attestationPrivKey.value(), serialDecimal, issuer, subject,
- validityNotBefore, validityNotAfter);
- if (!attestationKeyCertificate) {
+ optional<vector<uint8_t>> privKey = support::ecKeyPairGetPrivateKey(keyPair);
+ if (!privKey) {
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
IIdentityCredentialStore::STATUS_FAILED,
- "Error creating certificate for attestationPubKey"));
+ "Error getting private part of credentialKey"));
}
+ credentialPrivKey_ = privKey.value();
- // Concatenate the certificates to form the chain.
- vector<uint8_t> certificateChain;
- certificateChain.insert(certificateChain.end(), credentialPubKeyCertificate.value().begin(),
- credentialPubKeyCertificate.value().end());
- certificateChain.insert(certificateChain.end(), attestationKeyCertificate.value().begin(),
- attestationKeyCertificate.value().end());
-
- optional<vector<vector<uint8_t>>> splitCertChain =
- support::certificateChainSplit(certificateChain);
- if (!splitCertChain) {
- return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
- IIdentityCredentialStore::STATUS_FAILED, "Error splitting certificate chain"));
- }
+ // convert from vector<vector<uint8_t>>> to vector<Certificate>*
*outCertificateChain = vector<Certificate>();
- for (const vector<uint8_t>& cert : splitCertChain.value()) {
+ for (const vector<uint8_t>& cert : certificateChain_) {
Certificate c = Certificate();
c.encodedCertificate = byteStringToSigned(cert);
outCertificateChain->push_back(std::move(c));
diff --git a/identity/aidl/default/WritableIdentityCredential.h b/identity/aidl/default/WritableIdentityCredential.h
index b380f89..b182862 100644
--- a/identity/aidl/default/WritableIdentityCredential.h
+++ b/identity/aidl/default/WritableIdentityCredential.h
@@ -64,10 +64,13 @@
string docType_;
bool testCredential_;
- // These are set in initialize().
+ // This is set in initialize().
vector<uint8_t> storageKey_;
+
+ // These are set in getAttestationCertificate().
vector<uint8_t> credentialPrivKey_;
vector<uint8_t> credentialPubKey_;
+ vector<vector<uint8_t>> certificateChain_;
// These fields are initialized during startPersonalization()
size_t numAccessControlProfileRemaining_;
diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp
index 21ff440..cecc814 100644
--- a/identity/aidl/vts/Android.bp
+++ b/identity/aidl/vts/Android.bp
@@ -7,10 +7,11 @@
srcs: ["VtsHalIdentityTargetTest.cpp"],
shared_libs: [
"libbinder",
- "libcppbor",
- "android.hardware.identity-support-lib",
+ "libcrypto",
],
static_libs: [
+ "libcppbor",
+ "android.hardware.identity-support-lib",
"android.hardware.identity-cpp",
"android.hardware.keymaster-cpp",
],
diff --git a/identity/aidl/vts/VtsHalIdentityTargetTest.cpp b/identity/aidl/vts/VtsHalIdentityTargetTest.cpp
index 5abe5a2..ea37fdc 100644
--- a/identity/aidl/vts/VtsHalIdentityTargetTest.cpp
+++ b/identity/aidl/vts/VtsHalIdentityTargetTest.cpp
@@ -352,10 +352,15 @@
readerCertificate.value());
ASSERT_TRUE(readerSignature);
+ // Generate the key that will be used to sign AuthenticatedData.
+ vector<uint8_t> signingKeyBlob;
+ Certificate signingKeyCertificate;
+ ASSERT_TRUE(credential->generateSigningKeyPair(&signingKeyBlob, &signingKeyCertificate).isOk());
+
ASSERT_TRUE(credential
->startRetrieval(returnedSecureProfiles, authToken, itemsRequestBytes,
- sessionTranscriptBytes, readerSignature.value(),
- testEntriesEntryCounts)
+ signingKeyBlob, sessionTranscriptBytes,
+ readerSignature.value(), testEntriesEntryCounts)
.isOk());
for (const auto& entry : testEntries) {
@@ -377,14 +382,9 @@
EXPECT_EQ(content, entry.valueCbor);
}
- // Generate the key that will be used to sign AuthenticatedData.
- vector<uint8_t> signingKeyBlob;
- Certificate signingKeyCertificate;
- ASSERT_TRUE(credential->generateSigningKeyPair(&signingKeyBlob, &signingKeyCertificate).isOk());
-
vector<uint8_t> mac;
vector<uint8_t> deviceNameSpacesBytes;
- ASSERT_TRUE(credential->finishRetrieval(signingKeyBlob, &mac, &deviceNameSpacesBytes).isOk());
+ ASSERT_TRUE(credential->finishRetrieval(&mac, &deviceNameSpacesBytes).isOk());
cborPretty = support::cborPrettyPrint(deviceNameSpacesBytes, 32, {});
ASSERT_EQ(
"{\n"
diff --git a/identity/support/Android.bp b/identity/support/Android.bp
index 7b4546b..2b6c695 100644
--- a/identity/support/Android.bp
+++ b/identity/support/Android.bp
@@ -23,10 +23,14 @@
"include",
],
shared_libs: [
+ "android.hardware.keymaster@4.0",
"libcrypto",
"libbase",
"libhidlbase",
"libhardware",
+ "libkeymaster_portable",
+ "libsoft_attestation_cert",
+ "libpuresoftkeymasterdevice",
],
static_libs: [
"libcppbor",
diff --git a/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h b/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
index 4533ad9..507e914 100644
--- a/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
+++ b/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
@@ -21,6 +21,7 @@
#include <optional>
#include <string>
#include <tuple>
+#include <utility>
#include <vector>
namespace android {
@@ -106,6 +107,17 @@
// ---------------------------------------------------------------------------
// EC crypto functionality / abstraction (only supports P-256).
// ---------------------------------------------------------------------------
+// Creates an 256-bit EC key using the NID_X9_62_prime256v1 curve, returns the
+// PKCS#8 encoded key-pair. Also generates an attestation
+// certificate using the |challenge| and |applicationId|, and returns the generated
+// certificate in X.509 certificate chain format.
+//
+// The attestation time fields used will be the current time, and expires in one year.
+//
+// The first parameter of the return value is the keyPair generated, second return in
+// the pair is the attestation certificate generated.
+optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> createEcKeyPairAndAttestation(
+ 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.
diff --git a/identity/support/src/IdentityCredentialSupport.cpp b/identity/support/src/IdentityCredentialSupport.cpp
index e2828bf..bf6a5c3 100644
--- a/identity/support/src/IdentityCredentialSupport.cpp
+++ b/identity/support/src/IdentityCredentialSupport.cpp
@@ -47,6 +47,13 @@
#include <cppbor.h>
#include <cppbor_parse.h>
+#include <android/hardware/keymaster/4.0/types.h>
+#include <keymaster/authorization_set.h>
+#include <keymaster/contexts/pure_soft_keymaster_context.h>
+#include <keymaster/contexts/soft_attestation_cert.h>
+#include <keymaster/keymaster_tags.h>
+#include <keymaster/km_openssl/attestation_utils.h>
+
namespace android {
namespace hardware {
namespace identity {
@@ -816,6 +823,138 @@
return hmac;
}
+// Generates the attestation certificate with the parameters passed in. Note
+// that the passed in |activeTimeMilliSeconds| |expireTimeMilliSeconds| are in
+// milli seconds since epoch. We are setting them to milliseconds due to
+// requirement in AuthorizationSet KM_DATE fields. The certificate created is
+// actually in seconds.
+optional<vector<vector<uint8_t>>> createAttestation(const EVP_PKEY* key,
+ const vector<uint8_t>& applicationId,
+ const vector<uint8_t>& challenge,
+ uint64_t activeTimeMilliSeconds,
+ uint64_t expireTimeMilliSeconds) {
+ ::keymaster::AuthorizationSet auth_set(
+ ::keymaster::AuthorizationSetBuilder()
+ .Authorization(::keymaster::TAG_ATTESTATION_CHALLENGE, challenge.data(),
+ challenge.size())
+ .Authorization(::keymaster::TAG_ACTIVE_DATETIME, activeTimeMilliSeconds)
+ // Even though identity attestation hal said the application
+ // id should be in software enforced authentication set,
+ // keymaster portable lib expect the input in this
+ // parameter because the software enforced in input to keymaster
+ // refers to the key software enforced properties. And this
+ // parameter refers to properties of the attestation which
+ // includes app id.
+ .Authorization(::keymaster::TAG_ATTESTATION_APPLICATION_ID,
+ applicationId.data(), applicationId.size())
+ .Authorization(::keymaster::TAG_USAGE_EXPIRE_DATETIME, expireTimeMilliSeconds));
+
+ // Unique id and device id is not applicable for identity credential attestation,
+ // so we don't need to set those or application id.
+ ::keymaster::AuthorizationSet swEnforced(::keymaster::AuthorizationSetBuilder().Authorization(
+ ::keymaster::TAG_CREATION_DATETIME, activeTimeMilliSeconds));
+
+ ::keymaster::AuthorizationSet hwEnforced(
+ ::keymaster::AuthorizationSetBuilder()
+ .Authorization(::keymaster::TAG_PURPOSE, KM_PURPOSE_SIGN)
+ .Authorization(::keymaster::TAG_KEY_SIZE, 256)
+ .Authorization(::keymaster::TAG_ALGORITHM, KM_ALGORITHM_EC)
+ .Authorization(::keymaster::TAG_NO_AUTH_REQUIRED)
+ .Authorization(::keymaster::TAG_DIGEST, KM_DIGEST_SHA_2_256)
+ .Authorization(::keymaster::TAG_EC_CURVE, KM_EC_CURVE_P_256)
+ .Authorization(::keymaster::TAG_IDENTITY_CREDENTIAL_KEY));
+
+ const keymaster_cert_chain_t* attestation_chain =
+ ::keymaster::getAttestationChain(KM_ALGORITHM_EC, nullptr);
+
+ if (attestation_chain == nullptr) {
+ LOG(ERROR) << "Error getting attestation chain";
+ return {};
+ }
+
+ const keymaster_key_blob_t* attestation_signing_key =
+ ::keymaster::getAttestationKey(KM_ALGORITHM_EC, nullptr);
+ if (attestation_signing_key == nullptr) {
+ LOG(ERROR) << "Error getting attestation key";
+ return {};
+ }
+
+ keymaster_error_t error;
+ ::keymaster::CertChainPtr cert_chain_out;
+ ::keymaster::PureSoftKeymasterContext context;
+
+ // set identity version to 10 per hal requirements specified in IWriteableCredential.hal
+ // For now, the identity version in the attestation is set in the keymaster
+ // version field in the portable keymaster lib, which is a bit misleading.
+ uint identity_version = 10;
+ error = generate_attestation_from_EVP(key, swEnforced, hwEnforced, auth_set, context,
+ identity_version, *attestation_chain,
+ *attestation_signing_key, &cert_chain_out);
+
+ if (KM_ERROR_OK != error || !cert_chain_out) {
+ LOG(ERROR) << "Error generate attestation from EVP key" << error;
+ return {};
+ }
+
+ // translate certificate format from keymaster_cert_chain_t to vector<uint8_t>.
+ vector<vector<uint8_t>> attestationCertificate;
+ for (int i = 0; i < cert_chain_out->entry_count; i++) {
+ attestationCertificate.insert(
+ attestationCertificate.end(),
+ vector<uint8_t>(
+ cert_chain_out->entries[i].data,
+ cert_chain_out->entries[i].data + cert_chain_out->entries[i].data_length));
+ }
+
+ return attestationCertificate;
+}
+
+optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> createEcKeyPairAndAttestation(
+ const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId) {
+ auto ec_key = ::keymaster::EC_KEY_Ptr(EC_KEY_new());
+ auto pkey = ::keymaster::EVP_PKEY_Ptr(EVP_PKEY_new());
+ auto group = ::keymaster::EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+
+ if (ec_key.get() == nullptr || pkey.get() == nullptr) {
+ LOG(ERROR) << "Memory allocation failed";
+ return {};
+ }
+
+ if (EC_KEY_set_group(ec_key.get(), group.get()) != 1 ||
+ EC_KEY_generate_key(ec_key.get()) != 1 || EC_KEY_check_key(ec_key.get()) < 0) {
+ LOG(ERROR) << "Error generating key";
+ return {};
+ }
+
+ if (EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get()) != 1) {
+ LOG(ERROR) << "Error getting private key";
+ return {};
+ }
+
+ uint64_t now = time(nullptr);
+ 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 {};
+ }
+
+ int size = i2d_PrivateKey(pkey.get(), nullptr);
+ if (size == 0) {
+ LOG(ERROR) << "Error generating public key encoding";
+ return {};
+ }
+
+ vector<uint8_t> keyPair(size);
+ unsigned char* p = keyPair.data();
+ i2d_PrivateKey(pkey.get(), &p);
+
+ return make_pair(keyPair, attestationCert.value());
+}
+
optional<vector<uint8_t>> createEcKeyPair() {
auto ec_key = EC_KEY_Ptr(EC_KEY_new());
auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
diff --git a/keymaster/4.1/support/include/keymasterV4_1/keymaster_tags.h b/keymaster/4.1/support/include/keymasterV4_1/keymaster_tags.h
index 6c186f6..40eb142 100644
--- a/keymaster/4.1/support/include/keymasterV4_1/keymaster_tags.h
+++ b/keymaster/4.1/support/include/keymasterV4_1/keymaster_tags.h
@@ -101,6 +101,7 @@
DECLARE_KM_4_1_TYPED_TAG(EARLY_BOOT_ONLY);
DECLARE_KM_4_1_TYPED_TAG(DEVICE_UNIQUE_ATTESTATION);
DECLARE_KM_4_1_TYPED_TAG(STORAGE_KEY);
+DECLARE_KM_4_1_TYPED_TAG(IDENTITY_CREDENTIAL_KEY);
} // namespace android::hardware::keymaster::V4_1