Prerequsite changes for EVS multi-camera support
This change modifies existing methods and data types for upcoming EVS
multi-camera support.
- deliverFrame_1_1() and doneWithFrame_1_1() are modified to take
multiple buffer descriptors.
- setIntParameter() and getIntParameter() are changed to return multiple
parameter values.
- Device ID and timestamp fields are added to BufferDesc.
- EvsEvent is renamed as EvsEventDesc and Device Id is added.
Bug: 142275664
Test: VtsHalEvsV1_1TargetTest
Change-Id: I0415b2cb0642d1377f4d23a4e154080a66c81187
Signed-off-by: Changyeon Jo <changyeon@google.com>
diff --git a/automotive/evs/1.1/vts/functional/FrameHandler.cpp b/automotive/evs/1.1/vts/functional/FrameHandler.cpp
index 6d53652..38c709f 100644
--- a/automotive/evs/1.1/vts/functional/FrameHandler.cpp
+++ b/automotive/evs/1.1/vts/functional/FrameHandler.cpp
@@ -80,7 +80,7 @@
asyncStopStream();
// Wait until the stream has actually stopped
- std::unique_lock<std::mutex> lock(mLock);
+ std::unique_lock<std::mutex> lock(mEventLock);
if (mRunning) {
mEventSignal.wait(lock, [this]() { return !mRunning; });
}
@@ -96,9 +96,9 @@
return false;
}
- BufferDesc_1_1 buffer = mHeldBuffers.front();
+ hidl_vec<BufferDesc_1_1> buffers = mHeldBuffers.front();
mHeldBuffers.pop();
- mCamera->doneWithFrame_1_1(buffer);
+ mCamera->doneWithFrame_1_1(buffers);
return true;
}
@@ -138,50 +138,52 @@
}
-Return<void> FrameHandler::deliverFrame_1_1(const BufferDesc_1_1& bufDesc) {
- const AHardwareBuffer_Desc* pDesc =
- reinterpret_cast<const AHardwareBuffer_Desc *>(&bufDesc.buffer.description);
- ALOGD("Received a frame from the camera (%p)",
- bufDesc.buffer.nativeHandle.getNativeHandle());
+Return<void> FrameHandler::deliverFrame_1_1(const hidl_vec<BufferDesc_1_1>& buffers) {
+ for (auto&& buffer : buffers) {
+ const AHardwareBuffer_Desc* pDesc =
+ reinterpret_cast<const AHardwareBuffer_Desc *>(&buffer.buffer.description);
+ ALOGD("Received a frame from the camera (%p)",
+ buffer.buffer.nativeHandle.getNativeHandle());
- // Store a dimension of a received frame.
- mFrameWidth = pDesc->width;
- mFrameHeight = pDesc->height;
+ // Store a dimension of a received frame.
+ mFrameWidth = pDesc->width;
+ mFrameHeight = pDesc->height;
- // If we were given an opened display at construction time, then send the received
- // image back down the camera.
- if (mDisplay.get()) {
- // Get the output buffer we'll use to display the imagery
- BufferDesc_1_0 tgtBuffer = {};
- mDisplay->getTargetBuffer([&tgtBuffer](const BufferDesc_1_0& buff) {
- tgtBuffer = buff;
- }
- );
+ // If we were given an opened display at construction time, then send the received
+ // image back down the camera.
+ if (mDisplay.get()) {
+ // Get the output buffer we'll use to display the imagery
+ BufferDesc_1_0 tgtBuffer = {};
+ mDisplay->getTargetBuffer([&tgtBuffer](const BufferDesc_1_0& buff) {
+ tgtBuffer = buff;
+ }
+ );
- if (tgtBuffer.memHandle == nullptr) {
- printf("Didn't get target buffer - frame lost\n");
- ALOGE("Didn't get requested output buffer -- skipping this frame.");
- } else {
- // Copy the contents of the of buffer.memHandle into tgtBuffer
- copyBufferContents(tgtBuffer, bufDesc);
-
- // Send the target buffer back for display
- Return<EvsResult> result = mDisplay->returnTargetBufferForDisplay(tgtBuffer);
- if (!result.isOk()) {
- printf("HIDL error on display buffer (%s)- frame lost\n",
- result.description().c_str());
- ALOGE("Error making the remote function call. HIDL said %s",
- result.description().c_str());
- } else if (result != EvsResult::OK) {
- printf("Display reported error - frame lost\n");
- ALOGE("We encountered error %d when returning a buffer to the display!",
- (EvsResult) result);
+ if (tgtBuffer.memHandle == nullptr) {
+ printf("Didn't get target buffer - frame lost\n");
+ ALOGE("Didn't get requested output buffer -- skipping this frame.");
} else {
- // Everything looks good!
- // Keep track so tests or watch dogs can monitor progress
- mLock.lock();
- mFramesDisplayed++;
- mLock.unlock();
+ // Copy the contents of the of buffer.memHandle into tgtBuffer
+ copyBufferContents(tgtBuffer, buffer);
+
+ // Send the target buffer back for display
+ Return<EvsResult> result = mDisplay->returnTargetBufferForDisplay(tgtBuffer);
+ if (!result.isOk()) {
+ printf("HIDL error on display buffer (%s)- frame lost\n",
+ result.description().c_str());
+ ALOGE("Error making the remote function call. HIDL said %s",
+ result.description().c_str());
+ } else if (result != EvsResult::OK) {
+ printf("Display reported error - frame lost\n");
+ ALOGE("We encountered error %d when returning a buffer to the display!",
+ (EvsResult) result);
+ } else {
+ // Everything looks good!
+ // Keep track so tests or watch dogs can monitor progress
+ mLock.lock();
+ mFramesDisplayed++;
+ mLock.unlock();
+ }
}
}
}
@@ -191,11 +193,11 @@
case eAutoReturn:
// Send the camera buffer back now that the client has seen it
ALOGD("Calling doneWithFrame");
- mCamera->doneWithFrame_1_1(bufDesc);
+ mCamera->doneWithFrame_1_1(buffers);
break;
case eNoAutoReturn:
- // Hang onto the buffer handle for now -- the client will return it explicitly later
- mHeldBuffers.push(bufDesc);
+ // Hang onto the buffer handles for now -- the client will return it explicitly later
+ mHeldBuffers.push(buffers);
}
mLock.lock();
@@ -209,7 +211,7 @@
}
-Return<void> FrameHandler::notify(const EvsEvent& event) {
+Return<void> FrameHandler::notify(const EvsEventDesc& event) {
// Local flag we use to keep track of when the stream is stopping
mLock.lock();
mLatestEventDesc = event;
@@ -223,7 +225,7 @@
ALOGD("Received an event %s", eventToString(mLatestEventDesc.aType));
}
mLock.unlock();
- mEventSignal.notify_all();
+ mEventSignal.notify_one();
return Void();
}
@@ -342,19 +344,20 @@
}
}
-bool FrameHandler::waitForEvent(const EvsEventType aTargetEvent,
- EvsEvent &event) {
+bool FrameHandler::waitForEvent(const EvsEventDesc& aTargetEvent,
+ EvsEventDesc& aReceivedEvent) {
// Wait until we get an expected parameter change event.
- std::unique_lock<std::mutex> lock(mLock);
+ std::unique_lock<std::mutex> lock(mEventLock);
auto now = std::chrono::system_clock::now();
bool result = mEventSignal.wait_until(lock, now + 5s,
- [this, aTargetEvent, &event](){
- bool flag = mLatestEventDesc.aType == aTargetEvent;
- if (flag) {
- event.aType = mLatestEventDesc.aType;
- event.payload[0] = mLatestEventDesc.payload[0];
- event.payload[1] = mLatestEventDesc.payload[1];
- }
+ [this, aTargetEvent, &aReceivedEvent](){
+ bool flag = (mLatestEventDesc.aType == aTargetEvent.aType) &&
+ (mLatestEventDesc.payload[0] == aTargetEvent.payload[0]) &&
+ (mLatestEventDesc.payload[1] == aTargetEvent.payload[1]);
+
+ aReceivedEvent.aType = mLatestEventDesc.aType;
+ aReceivedEvent.payload[0] = mLatestEventDesc.payload[0];
+ aReceivedEvent.payload[1] = mLatestEventDesc.payload[1];
return flag;
}
diff --git a/automotive/evs/1.1/vts/functional/FrameHandler.h b/automotive/evs/1.1/vts/functional/FrameHandler.h
index e5f1b8f..51e5a86 100644
--- a/automotive/evs/1.1/vts/functional/FrameHandler.h
+++ b/automotive/evs/1.1/vts/functional/FrameHandler.h
@@ -73,8 +73,8 @@
bool isRunning();
void waitForFrameCount(unsigned frameCount);
- bool waitForEvent(const EvsEventType aTargetEvent,
- EvsEvent &eventDesc);
+ bool waitForEvent(const EvsEventDesc& aTargetEvent,
+ EvsEventDesc& aReceivedEvent);
void getFramesCounters(unsigned* received, unsigned* displayed);
void getFrameDimension(unsigned* width, unsigned* height);
@@ -83,8 +83,8 @@
Return<void> deliverFrame(const BufferDesc_1_0& buffer) override;
// Implementation for ::android::hardware::automotive::evs::V1_1::IEvsCameraStream
- Return<void> deliverFrame_1_1(const BufferDesc_1_1& buffer) override;
- Return<void> notify(const EvsEvent& event) override;
+ Return<void> deliverFrame_1_1(const hidl_vec<BufferDesc_1_1>& buffer) override;
+ Return<void> notify(const EvsEventDesc& event) override;
// Local implementation details
bool copyBufferContents(const BufferDesc_1_0& tgtBuffer, const BufferDesc_1_1& srcBuffer);
@@ -99,17 +99,18 @@
// Since we get frames delivered to us asynchronously via the IEvsCameraStream interface,
// we need to protect all member variables that may be modified while we're streaming
// (ie: those below)
- std::mutex mLock;
- std::condition_variable mEventSignal;
- std::condition_variable mFrameSignal;
+ std::mutex mLock;
+ std::mutex mEventLock;
+ std::condition_variable mEventSignal;
+ std::condition_variable mFrameSignal;
+ std::queue<hidl_vec<BufferDesc_1_1>> mHeldBuffers;
- std::queue<BufferDesc_1_1> mHeldBuffers;
bool mRunning = false;
unsigned mFramesReceived = 0; // Simple counter -- rolls over eventually!
unsigned mFramesDisplayed = 0; // Simple counter -- rolls over eventually!
unsigned mFrameWidth = 0;
unsigned mFrameHeight = 0;
- EvsEvent mLatestEventDesc;
+ EvsEventDesc mLatestEventDesc;
};
diff --git a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
index 1d3fd87..8847a95 100644
--- a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
+++ b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
@@ -67,6 +67,7 @@
using ::android::hardware::hidl_handle;
using ::android::hardware::hidl_string;
using ::android::sp;
+using ::android::wp;
using ::android::hardware::camera::device::V3_2::Stream;
using ::android::hardware::automotive::evs::V1_0::DisplayDesc;
using ::android::hardware::automotive::evs::V1_0::DisplayState;
@@ -117,7 +118,15 @@
mIsHwModule = !service_name.compare(kEnumeratorName);
}
- virtual void TearDown() override {}
+ virtual void TearDown() override {
+ // Attempt to close any active camera
+ for (auto &&c : activeCameras) {
+ sp<IEvsCamera_1_1> cam = c.promote();
+ if (cam != nullptr) {
+ pEnumerator->closeCamera(cam);
+ }
+ }
+ }
protected:
void loadCameraList() {
@@ -141,10 +150,12 @@
ASSERT_GE(cameraInfo.size(), 1u);
}
- sp<IEvsEnumerator> pEnumerator; // Every test needs access to the service
- std::vector <CameraDesc> cameraInfo; // Empty unless/until loadCameraList() is called
- bool mIsHwModule; // boolean to tell current module under testing
- // is HW module implementation.
+ sp<IEvsEnumerator> pEnumerator; // Every test needs access to the service
+ 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
+ // needed to be cleaned up.
};
@@ -169,11 +180,15 @@
// Open and close each camera twice
for (auto&& cam: cameraInfo) {
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);
ASSERT_NE(pCam, nullptr);
+ // Store a camera handle for a clean-up
+ activeCameras.push_back(pCam);
+
// Verify that this camera self-identifies correctly
pCam->getCameraInfo_1_1([&cam](CameraDesc desc) {
ALOGD("Found camera %s", desc.v1.cameraId.c_str());
@@ -206,11 +221,15 @@
// Open and close each camera twice
for (auto&& cam: cameraInfo) {
+ activeCameras.clear();
sp<IEvsCamera_1_1> pCam =
IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
.withDefault(nullptr);
ASSERT_NE(pCam, nullptr);
+ // Store a camera handle for a clean-up
+ activeCameras.push_back(pCam);
+
// Verify that this camera self-identifies correctly
pCam->getCameraInfo_1_1([&cam](CameraDesc desc) {
ALOGD("Found camera %s", desc.v1.cameraId.c_str());
@@ -221,9 +240,13 @@
sp<IEvsCamera_1_1> pCam2 =
IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
.withDefault(nullptr);
- ASSERT_NE(pCam, pCam2);
ASSERT_NE(pCam2, nullptr);
+ // Store a camera handle for a clean-up
+ activeCameras.push_back(pCam2);
+
+ ASSERT_NE(pCam, pCam2);
+
Return<EvsResult> result = pCam->setMaxFramesInFlight(2);
if (mIsHwModule) {
// Verify that the old camera rejects calls via HW module.
@@ -268,11 +291,15 @@
// Test each reported camera
for (auto&& cam: cameraInfo) {
+ activeCameras.clear();
sp<IEvsCamera_1_1> pCam =
IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
.withDefault(nullptr);
ASSERT_NE(pCam, nullptr);
+ // Store a camera handle for a clean-up
+ activeCameras.push_back(pCam);
+
// Set up a frame receiver object which will fire up its own thread
sp<FrameHandler> frameHandler = new FrameHandler(pCam, cam,
nullptr,
@@ -340,12 +367,15 @@
// Test each reported camera
for (auto&& cam: cameraInfo) {
-
+ activeCameras.clear();
sp<IEvsCamera_1_1> pCam =
IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
.withDefault(nullptr);
ASSERT_NE(pCam, nullptr);
+ // Store a camera handle for a clean-up
+ activeCameras.push_back(pCam);
+
// Ask for a crazy number of buffers in flight to ensure it errors correctly
Return<EvsResult> badResult = pCam->setMaxFramesInFlight(0xFFFFFFFF);
EXPECT_EQ(EvsResult::BUFFER_NOT_AVAILABLE, badResult);
@@ -416,11 +446,15 @@
// Test each reported camera
for (auto&& cam: cameraInfo) {
+ activeCameras.clear();
sp<IEvsCamera_1_1> pCam =
IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
.withDefault(nullptr);
ASSERT_NE(pCam, nullptr);
+ // Store a camera handle for a clean-up
+ activeCameras.push_back(pCam);
+
// Set up a frame receiver object which will fire up its own thread.
sp<FrameHandler> frameHandler = new FrameHandler(pCam, cam,
pDisplay,
@@ -484,17 +518,24 @@
// 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))
.withDefault(nullptr);
ASSERT_NE(pCam0, nullptr);
+ // Store a camera handle for a clean-up
+ activeCameras.push_back(pCam0);
+
sp<IEvsCamera_1_1> pCam1 =
IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
.withDefault(nullptr);
ASSERT_NE(pCam1, nullptr);
+ // Store a camera handle for a clean-up
+ activeCameras.push_back(pCam1);
+
// Set up per-client frame receiver objects which will fire up its own thread
sp<FrameHandler> frameHandler0 = new FrameHandler(pCam0, cam,
nullptr,
@@ -575,12 +616,16 @@
// Test each reported camera
Return<EvsResult> result = EvsResult::OK;
for (auto&& cam: cameraInfo) {
+ activeCameras.clear();
// Create a camera client
sp<IEvsCamera_1_1> pCam =
IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
.withDefault(nullptr);
ASSERT_NE(pCam, nullptr);
+ // Store a camera
+ activeCameras.push_back(pCam);
+
// Get the parameter list
std::vector<CameraParam> cmds;
pCam->getParameterList([&cmds](hidl_vec<CameraParam> cmdList) {
@@ -626,48 +671,54 @@
EvsResult result = EvsResult::OK;
if (cmd == CameraParam::ABSOLUTE_FOCUS) {
// Try to turn off auto-focus
- int32_t val1 = 0;
- pCam->getIntParameter(CameraParam::AUTO_FOCUS,
- [&result, &val1](auto status, auto value) {
+ std::vector<int32_t> values;
+ pCam->setIntParameter(CameraParam::AUTO_FOCUS, 0,
+ [&result, &values](auto status, auto effectiveValues) {
result = status;
if (status == EvsResult::OK) {
- val1 = value;
+ for (auto &&v : effectiveValues) {
+ values.push_back(v);
+ }
}
});
- if (val1 != 0) {
- pCam->setIntParameter(CameraParam::AUTO_FOCUS, 0,
- [&result, &val1](auto status, auto effectiveValue) {
- result = status;
- val1 = effectiveValue;
- });
- ASSERT_EQ(EvsResult::OK, result);
- ASSERT_EQ(val1, 0);
+ ASSERT_EQ(EvsResult::OK, result);
+ for (auto &&v : values) {
+ ASSERT_EQ(v, 0);
}
}
// Try to program a parameter with a random value [minVal, maxVal]
int32_t val0 = minVal + (std::rand() % (maxVal - minVal));
- int32_t val1 = 0;
+ std::vector<int32_t> values;
// Rounding down
val0 = val0 - (val0 % step);
pCam->setIntParameter(cmd, val0,
- [&result, &val1](auto status, auto effectiveValue) {
+ [&result, &values](auto status, auto effectiveValues) {
result = status;
- val1 = effectiveValue;
+ if (status == EvsResult::OK) {
+ for (auto &&v : effectiveValues) {
+ values.push_back(v);
+ }
+ }
});
ASSERT_EQ(EvsResult::OK, result);
+ values.clear();
pCam->getIntParameter(cmd,
- [&result, &val1](auto status, auto value) {
+ [&result, &values](auto status, auto readValues) {
result = status;
if (status == EvsResult::OK) {
- val1 = value;
+ for (auto &&v : readValues) {
+ values.push_back(v);
+ }
}
});
ASSERT_EQ(EvsResult::OK, result);
- ASSERT_EQ(val0, val1) << "Values are not matched.";
+ for (auto &&v : values) {
+ ASSERT_EQ(val0, v) << "Values are not matched.";
+ }
}
result = pCam->unsetMaster();
@@ -704,16 +755,24 @@
// Test each reported camera
for (auto&& cam: cameraInfo) {
+ activeCameras.clear();
// Create two camera clients.
sp<IEvsCamera_1_1> pCamMaster =
IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
.withDefault(nullptr);
ASSERT_NE(pCamMaster, nullptr);
+
+ // Store a camera handle for a clean-up
+ activeCameras.push_back(pCamMaster);
+
sp<IEvsCamera_1_1> pCamNonMaster =
IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
.withDefault(nullptr);
ASSERT_NE(pCamNonMaster, nullptr);
+ // Store a camera handle for a clean-up
+ activeCameras.push_back(pCamNonMaster);
+
// Set up per-client frame receiver objects which will fire up its own thread
sp<FrameHandler> frameHandlerMaster =
new FrameHandler(pCamMaster, cam,
@@ -750,13 +809,15 @@
// Non-master client expects to receive a master role relesed
// notification.
- EvsEvent aNotification = {};
+ EvsEventDesc aTargetEvent = {};
+ EvsEventDesc aNotification = {};
// Release a master role.
pCamMaster->unsetMaster();
// Verify a change notification.
- frameHandlerNonMaster->waitForEvent(EvsEventType::MASTER_RELEASED, aNotification);
+ aTargetEvent.aType = EvsEventType::MASTER_RELEASED;
+ frameHandlerNonMaster->waitForEvent(aTargetEvent, aNotification);
ASSERT_EQ(EvsEventType::MASTER_RELEASED,
static_cast<EvsEventType>(aNotification.aType));
@@ -772,7 +833,8 @@
frameHandlerNonMaster->shutdown();
// Verify a change notification.
- frameHandlerMaster->waitForEvent(EvsEventType::MASTER_RELEASED, aNotification);
+ aTargetEvent.aType = EvsEventType::MASTER_RELEASED;
+ frameHandlerMaster->waitForEvent(aTargetEvent, aNotification);
ASSERT_EQ(EvsEventType::MASTER_RELEASED,
static_cast<EvsEventType>(aNotification.aType));
@@ -810,16 +872,24 @@
// Test each reported camera
for (auto&& cam: cameraInfo) {
+ activeCameras.clear();
// Create two camera clients.
sp<IEvsCamera_1_1> pCamMaster =
IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
.withDefault(nullptr);
ASSERT_NE(pCamMaster, nullptr);
+
+ // Store a camera handle for a clean-up
+ activeCameras.push_back(pCamMaster);
+
sp<IEvsCamera_1_1> pCamNonMaster =
IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
.withDefault(nullptr);
ASSERT_NE(pCamNonMaster, nullptr);
+ // Store a camera handle for a clean-up
+ activeCameras.push_back(pCamNonMaster);
+
// Get the parameter list
std::vector<CameraParam> camMasterCmds, camNonMasterCmds;
pCamMaster->getParameterList([&camMasterCmds](hidl_vec<CameraParam> cmdList) {
@@ -879,7 +949,7 @@
frameHandlerNonMaster->waitForFrameCount(1);
int32_t val0 = 0;
- int32_t val1 = 0;
+ std::vector<int32_t> values;
for (auto &cmd : camMasterCmds) {
// Get a valid parameter value range
int32_t minVal, maxVal, step;
@@ -895,14 +965,19 @@
EvsResult result = EvsResult::OK;
if (cmd == CameraParam::ABSOLUTE_FOCUS) {
// Try to turn off auto-focus
- int32_t val1 = 1;
pCamMaster->setIntParameter(CameraParam::AUTO_FOCUS, 0,
- [&result, &val1](auto status, auto effectiveValue) {
+ [&result, &values](auto status, auto effectiveValues) {
result = status;
- val1 = effectiveValue;
+ if (status == EvsResult::OK) {
+ for (auto &&v : effectiveValues) {
+ values.push_back(v);
+ }
+ }
});
ASSERT_EQ(EvsResult::OK, result);
- ASSERT_EQ(val1, 0);
+ for (auto &&v : values) {
+ ASSERT_EQ(v, 0);
+ }
}
// Try to program a parameter
@@ -910,45 +985,63 @@
// Rounding down
val0 = val0 - (val0 % step);
+ values.clear();
pCamMaster->setIntParameter(cmd, val0,
- [&result, &val1](auto status, auto effectiveValue) {
- result = status;
- val1 = effectiveValue;
- });
- ASSERT_EQ(EvsResult::OK, result);
-
- // Wait a moment
- sleep(1);
-
- // Non-master client expects to receive a parameter change notification
- // whenever a master client adjusts it.
- EvsEvent aNotification = {};
-
- pCamMaster->getIntParameter(cmd,
- [&result, &val1](auto status, auto value) {
+ [&result, &values](auto status, auto effectiveValues) {
result = status;
if (status == EvsResult::OK) {
- val1 = value;
+ for (auto &&v : effectiveValues) {
+ values.push_back(v);
+ }
}
});
ASSERT_EQ(EvsResult::OK, result);
- ASSERT_EQ(val0, val1) << "Values are not matched.";
+
+ // Non-master client expects to receive a parameter change notification
+ // whenever a master client adjusts it.
+ EvsEventDesc aTargetEvent = {};
+ EvsEventDesc aNotification = {};
+
+ values.clear();
+ pCamMaster->getIntParameter(cmd,
+ [&result, &values](auto status, auto readValues) {
+ result = status;
+ if (status == EvsResult::OK) {
+ for (auto &&v : readValues) {
+ values.push_back(v);
+ }
+ }
+ });
+ ASSERT_EQ(EvsResult::OK, result);
+ for (auto &&v : values) {
+ ASSERT_EQ(val0, v) << "Values are not matched.";
+ }
// Verify a change notification
- frameHandlerNonMaster->waitForEvent(EvsEventType::PARAMETER_CHANGED, aNotification);
+ aTargetEvent.aType = EvsEventType::PARAMETER_CHANGED;
+ aTargetEvent.payload[0] = static_cast<uint32_t>(cmd);
+ aTargetEvent.payload[1] = static_cast<uint32_t>(val0);
+ frameHandlerNonMaster->waitForEvent(aTargetEvent, aNotification);
ASSERT_EQ(EvsEventType::PARAMETER_CHANGED,
static_cast<EvsEventType>(aNotification.aType));
ASSERT_EQ(cmd,
static_cast<CameraParam>(aNotification.payload[0]));
- ASSERT_EQ(val1,
- static_cast<int32_t>(aNotification.payload[1]));
+ for (auto &&v : values) {
+ ASSERT_EQ(v,
+ static_cast<int32_t>(aNotification.payload[1]));
+ }
}
// Try to adjust a parameter via non-master client
+ values.clear();
pCamNonMaster->setIntParameter(camNonMasterCmds[0], val0,
- [&result, &val1](auto status, auto effectiveValue) {
+ [&result, &values](auto status, auto effectiveValues) {
result = status;
- val1 = effectiveValue;
+ if (status == EvsResult::OK) {
+ for (auto &&v : effectiveValues) {
+ values.push_back(v);
+ }
+ }
});
ASSERT_EQ(EvsResult::INVALID_ARG, result);
@@ -961,10 +1054,15 @@
ASSERT_EQ(EvsResult::OK, result);
// Try to adjust a parameter after being retired
+ values.clear();
pCamMaster->setIntParameter(camMasterCmds[0], val0,
- [&result, &val1](auto status, auto effectiveValue) {
+ [&result, &values](auto status, auto effectiveValues) {
result = status;
- val1 = effectiveValue;
+ if (status == EvsResult::OK) {
+ for (auto &&v : effectiveValues) {
+ values.push_back(v);
+ }
+ }
});
ASSERT_EQ(EvsResult::INVALID_ARG, result);
@@ -986,16 +1084,22 @@
);
EvsResult result = EvsResult::OK;
+ values.clear();
if (cmd == CameraParam::ABSOLUTE_FOCUS) {
// Try to turn off auto-focus
- int32_t val1 = 1;
pCamNonMaster->setIntParameter(CameraParam::AUTO_FOCUS, 0,
- [&result, &val1](auto status, auto effectiveValue) {
+ [&result, &values](auto status, auto effectiveValues) {
result = status;
- val1 = effectiveValue;
+ if (status == EvsResult::OK) {
+ for (auto &&v : effectiveValues) {
+ values.push_back(v);
+ }
+ }
});
ASSERT_EQ(EvsResult::OK, result);
- ASSERT_EQ(val1, 0);
+ for (auto &&v : values) {
+ ASSERT_EQ(v, 0);
+ }
}
// Try to program a parameter
@@ -1003,38 +1107,51 @@
// Rounding down
val0 = val0 - (val0 % step);
+ values.clear();
pCamNonMaster->setIntParameter(cmd, val0,
- [&result, &val1](auto status, auto effectiveValue) {
- result = status;
- val1 = effectiveValue;
- });
- ASSERT_EQ(EvsResult::OK, result);
-
- // Wait a moment
- sleep(1);
-
- // Non-master client expects to receive a parameter change notification
- // whenever a master client adjusts it.
- EvsEvent aNotification = {};
-
- pCamNonMaster->getIntParameter(cmd,
- [&result, &val1](auto status, auto value) {
+ [&result, &values](auto status, auto effectiveValues) {
result = status;
if (status == EvsResult::OK) {
- val1 = value;
+ for (auto &&v : effectiveValues) {
+ values.push_back(v);
+ }
}
});
ASSERT_EQ(EvsResult::OK, result);
- ASSERT_EQ(val0, val1) << "Values are not matched.";
+
+ // Non-master client expects to receive a parameter change notification
+ // whenever a master client adjusts it.
+ EvsEventDesc aTargetEvent = {};
+ EvsEventDesc aNotification = {};
+
+ values.clear();
+ pCamNonMaster->getIntParameter(cmd,
+ [&result, &values](auto status, auto readValues) {
+ result = status;
+ if (status == EvsResult::OK) {
+ for (auto &&v : readValues) {
+ values.push_back(v);
+ }
+ }
+ });
+ ASSERT_EQ(EvsResult::OK, result);
+ for (auto &&v : values) {
+ ASSERT_EQ(val0, v) << "Values are not matched.";
+ }
// Verify a change notification
- frameHandlerMaster->waitForEvent(EvsEventType::PARAMETER_CHANGED, aNotification);
+ aTargetEvent.aType = EvsEventType::PARAMETER_CHANGED;
+ aTargetEvent.payload[0] = static_cast<uint32_t>(cmd);
+ aTargetEvent.payload[1] = static_cast<uint32_t>(val0);
+ frameHandlerMaster->waitForEvent(aTargetEvent, aNotification);
ASSERT_EQ(EvsEventType::PARAMETER_CHANGED,
static_cast<EvsEventType>(aNotification.aType));
ASSERT_EQ(cmd,
static_cast<CameraParam>(aNotification.payload[0]));
- ASSERT_EQ(val1,
- static_cast<int32_t>(aNotification.payload[1]));
+ for (auto &&v : values) {
+ ASSERT_EQ(v,
+ static_cast<int32_t>(aNotification.payload[1]));
+ }
}
// New master retires from a master role
@@ -1078,17 +1195,25 @@
// 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))
.withDefault(nullptr);
ASSERT_NE(pCam0, nullptr);
+ // Store a camera handle for a clean-up
+ activeCameras.push_back(pCam0);
+
sp<IEvsCamera_1_1> pCam1 =
IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
.withDefault(nullptr);
ASSERT_NE(pCam1, nullptr);
+ // Store a camera handle for a clean-up
+ activeCameras.push_back(pCam1);
+
// Get the parameter list; this test will use the first command in both
// lists.
std::vector<CameraParam> cam0Cmds, cam1Cmds;
@@ -1144,108 +1269,141 @@
}
);
+ // Client1 becomes a master
+ result = pCam1->setMaster();
+ ASSERT_EQ(EvsResult::OK, result);
+
+ std::vector<int32_t> values;
+ EvsEventDesc aTargetEvent = {};
+ EvsEventDesc aNotification = {};
if (cam1Cmds[0] == CameraParam::ABSOLUTE_FOCUS) {
// Try to turn off auto-focus
- int32_t val1 = 0;
- pCam1->getIntParameter(CameraParam::AUTO_FOCUS,
- [&result, &val1](auto status, auto value) {
+ pCam1->setIntParameter(CameraParam::AUTO_FOCUS, 0,
+ [&result, &values](auto status, auto effectiveValues) {
result = status;
if (status == EvsResult::OK) {
- val1 = value;
+ for (auto &&v : effectiveValues) {
+ values.push_back(v);
+ }
}
});
- if (val1 != 0) {
- pCam1->setIntParameter(CameraParam::AUTO_FOCUS, 0,
- [&result, &val1](auto status, auto effectiveValue) {
- result = status;
- val1 = effectiveValue;
- });
- ASSERT_EQ(EvsResult::OK, result);
- ASSERT_EQ(val1, 0);
+ ASSERT_EQ(EvsResult::OK, result);
+ for (auto &&v : values) {
+ ASSERT_EQ(v, 0);
}
+
+ // Make sure AUTO_FOCUS is off.
+ aTargetEvent.aType = EvsEventType::PARAMETER_CHANGED;
+ aTargetEvent.payload[0] = static_cast<uint32_t>(CameraParam::AUTO_FOCUS);
+ aTargetEvent.payload[1] = 0;
+ bool timeout =
+ frameHandler0->waitForEvent(aTargetEvent, aNotification);
+ ASSERT_FALSE(timeout) << "Expected event does not arrive";
}
// Try to program a parameter with a random value [minVal, maxVal]
int32_t val0 = minVal + (std::rand() % (maxVal - minVal));
- int32_t val1 = 0;
// Rounding down
val0 = val0 - (val0 % step);
-
- result = pCam1->setMaster();
- ASSERT_EQ(EvsResult::OK, result);
-
+ values.clear();
pCam1->setIntParameter(cam1Cmds[0], val0,
- [&result, &val1](auto status, auto effectiveValue) {
+ [&result, &values](auto status, auto effectiveValues) {
result = status;
- val1 = effectiveValue;
+ if (status == EvsResult::OK) {
+ for (auto &&v : effectiveValues) {
+ values.push_back(v);
+ }
+ }
});
ASSERT_EQ(EvsResult::OK, result);
+ for (auto &&v : values) {
+ ASSERT_EQ(val0, v);
+ }
// Verify a change notification
- EvsEvent aNotification = {};
+ aTargetEvent.aType = EvsEventType::PARAMETER_CHANGED;
+ aTargetEvent.payload[0] = static_cast<uint32_t>(cam1Cmds[0]);
+ aTargetEvent.payload[1] = static_cast<uint32_t>(val0);
bool timeout =
- frameHandler0->waitForEvent(EvsEventType::PARAMETER_CHANGED, aNotification);
+ frameHandler0->waitForEvent(aTargetEvent, aNotification);
ASSERT_FALSE(timeout) << "Expected event does not arrive";
ASSERT_EQ(static_cast<EvsEventType>(aNotification.aType),
EvsEventType::PARAMETER_CHANGED);
ASSERT_EQ(static_cast<CameraParam>(aNotification.payload[0]),
cam1Cmds[0]);
- ASSERT_EQ(val1,
- static_cast<int32_t>(aNotification.payload[1]));
+ for (auto &&v : values) {
+ ASSERT_EQ(v, static_cast<int32_t>(aNotification.payload[1]));
+ }
// Client 0 steals a master role
ASSERT_EQ(EvsResult::OK, pCam0->forceMaster(pDisplay));
- frameHandler1->waitForEvent(EvsEventType::MASTER_RELEASED, aNotification);
+ aTargetEvent.aType = EvsEventType::MASTER_RELEASED;
+ aTargetEvent.payload[0] = 0;
+ aTargetEvent.payload[1] = 0;
+ frameHandler1->waitForEvent(aTargetEvent, aNotification);
ASSERT_EQ(static_cast<EvsEventType>(aNotification.aType),
EvsEventType::MASTER_RELEASED);
// Client 0 programs a parameter
val0 = minVal + (std::rand() % (maxVal - minVal));
- val1 = 0;
// Rounding down
val0 = val0 - (val0 % step);
if (cam0Cmds[0] == CameraParam::ABSOLUTE_FOCUS) {
// Try to turn off auto-focus
- int32_t val1 = 0;
- pCam0->getIntParameter(CameraParam::AUTO_FOCUS,
- [&result, &val1](auto status, auto value) {
+ values.clear();
+ pCam0->setIntParameter(CameraParam::AUTO_FOCUS, 0,
+ [&result, &values](auto status, auto effectiveValues) {
result = status;
if (status == EvsResult::OK) {
- val1 = value;
+ for (auto &&v : effectiveValues) {
+ values.push_back(v);
+ }
}
});
- if (val1 != 0) {
- pCam0->setIntParameter(CameraParam::AUTO_FOCUS, 0,
- [&result, &val1](auto status, auto effectiveValue) {
- result = status;
- val1 = effectiveValue;
- });
- ASSERT_EQ(EvsResult::OK, result);
- ASSERT_EQ(val1, 0);
+ ASSERT_EQ(EvsResult::OK, result);
+ for (auto &&v : values) {
+ ASSERT_EQ(v, 0);
}
+
+ // Make sure AUTO_FOCUS is off.
+ aTargetEvent.aType = EvsEventType::PARAMETER_CHANGED;
+ aTargetEvent.payload[0] = static_cast<uint32_t>(CameraParam::AUTO_FOCUS);
+ aTargetEvent.payload[1] = 0;
+ bool timeout =
+ frameHandler1->waitForEvent(aTargetEvent, aNotification);
+ ASSERT_FALSE(timeout) << "Expected event does not arrive";
}
+ values.clear();
pCam0->setIntParameter(cam0Cmds[0], val0,
- [&result, &val1](auto status, auto effectiveValue) {
+ [&result, &values](auto status, auto effectiveValues) {
result = status;
- val1 = effectiveValue;
+ if (status == EvsResult::OK) {
+ for (auto &&v : effectiveValues) {
+ values.push_back(v);
+ }
+ }
});
ASSERT_EQ(EvsResult::OK, result);
// Verify a change notification
+ aTargetEvent.aType = EvsEventType::PARAMETER_CHANGED;
+ aTargetEvent.payload[0] = static_cast<uint32_t>(cam0Cmds[0]);
+ aTargetEvent.payload[1] = static_cast<uint32_t>(val0);
timeout =
- frameHandler1->waitForEvent(EvsEventType::PARAMETER_CHANGED, aNotification);
+ frameHandler1->waitForEvent(aTargetEvent, aNotification);
ASSERT_FALSE(timeout) << "Expected event does not arrive";
ASSERT_EQ(static_cast<EvsEventType>(aNotification.aType),
EvsEventType::PARAMETER_CHANGED);
ASSERT_EQ(static_cast<CameraParam>(aNotification.payload[0]),
cam0Cmds[0]);
- ASSERT_EQ(val1,
- static_cast<int32_t>(aNotification.payload[1]));
+ for (auto &&v : values) {
+ ASSERT_EQ(v, static_cast<int32_t>(aNotification.payload[1]));
+ }
// Turn off the display (yes, before the stream stops -- it should be handled)
pDisplay->setDisplayState(DisplayState::NOT_VISIBLE);
@@ -1282,6 +1440,7 @@
// 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;
@@ -1324,6 +1483,9 @@
.withDefault(nullptr);
ASSERT_NE(pCam, nullptr);
+ // Store a camera handle for a clean-up
+ activeCameras.push_back(pCam);
+
// Set up a frame receiver object which will fire up its own thread.
sp<FrameHandler> frameHandler = new FrameHandler(pCam, cam,
pDisplay,
@@ -1383,6 +1545,7 @@
// 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;
@@ -1427,6 +1590,9 @@
.withDefault(nullptr);
ASSERT_NE(pCam0, nullptr);
+ // Store a camera handle for a clean-up
+ activeCameras.push_back(pCam0);
+
// Try to create the second camera client with different stream
// configuration.
int32_t id = targetCfg.id;
@@ -1436,6 +1602,9 @@
.withDefault(nullptr);
ASSERT_EQ(pCam1, nullptr);
+ // Store a camera handle for a clean-up
+ activeCameras.push_back(pCam0);
+
// Try again with same stream configuration.
targetCfg.id = id;
pCam1 =