Camera: fix emulator deadlock
Test: Emulator FastBasicTest 100 iteration, CTS on real device
Bug: 63933389
Change-Id: I27013d64a9cb29cb95591dc0598afbb59ac96290
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 471b2c0..6421695 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -240,6 +240,7 @@
status_t res = OK;
std::vector<wp<Camera3StreamInterface>> streams;
+ nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
{
Mutex::Autolock l(mLock);
if (mStatus == STATUS_UNINITIALIZED) return res;
@@ -251,7 +252,6 @@
SET_ERR_L("Can't stop streaming");
// Continue to close device even in case of error
} else {
- nsecs_t maxExpectedDuration = getExpectedInFlightDurationLocked();
res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
if (res != OK) {
SET_ERR_L("Timeout waiting for HAL to drain (% " PRIi64 " ns)",
@@ -311,7 +311,6 @@
{
Mutex::Autolock l(mLock);
- mExpectedInflightDuration = 0;
mInterface->clear();
mOutputStreams.clear();
mInputStream.clear();
@@ -1142,6 +1141,7 @@
uint32_t width, uint32_t height, int format, int *id) {
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
+ nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
Mutex::Autolock l(mLock);
ALOGV("Camera %s: Creating new input stream %d: %d x %d, format %d",
mId.string(), mNextStreamId, width, height, format);
@@ -1162,7 +1162,7 @@
break;
case STATUS_ACTIVE:
ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
- res = internalPauseAndWaitLocked();
+ res = internalPauseAndWaitLocked(maxExpectedDuration);
if (res != OK) {
SET_ERR_L("Can't pause captures to reconfigure streams!");
return res;
@@ -1229,6 +1229,7 @@
int streamSetId, bool isShared, uint32_t consumerUsage) {
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
+ nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
Mutex::Autolock l(mLock);
ALOGV("Camera %s: Creating new stream %d: %d x %d, format %d, dataspace %d rotation %d"
" consumer usage 0x%x, isShared %d", mId.string(), mNextStreamId, width, height, format,
@@ -1250,7 +1251,7 @@
break;
case STATUS_ACTIVE:
ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
- res = internalPauseAndWaitLocked();
+ res = internalPauseAndWaitLocked(maxExpectedDuration);
if (res != OK) {
SET_ERR_L("Can't pause captures to reconfigure streams!");
return res;
@@ -1501,59 +1502,66 @@
}
Mutex::Autolock il(mInterfaceLock);
- Mutex::Autolock l(mLock);
- switch (mStatus) {
- case STATUS_ERROR:
- CLOGE("Device has encountered a serious error");
- return INVALID_OPERATION;
- case STATUS_UNINITIALIZED:
- CLOGE("Device is not initialized!");
- return INVALID_OPERATION;
- case STATUS_UNCONFIGURED:
- case STATUS_CONFIGURED:
- case STATUS_ACTIVE:
- // OK
- break;
- default:
- SET_ERR_L("Unexpected status: %d", mStatus);
- return INVALID_OPERATION;
- }
+ {
+ Mutex::Autolock l(mLock);
+ switch (mStatus) {
+ case STATUS_ERROR:
+ CLOGE("Device has encountered a serious error");
+ return INVALID_OPERATION;
+ case STATUS_UNINITIALIZED:
+ CLOGE("Device is not initialized!");
+ return INVALID_OPERATION;
+ case STATUS_UNCONFIGURED:
+ case STATUS_CONFIGURED:
+ case STATUS_ACTIVE:
+ // OK
+ break;
+ default:
+ SET_ERR_L("Unexpected status: %d", mStatus);
+ return INVALID_OPERATION;
+ }
- if (!mRequestTemplateCache[templateId].isEmpty()) {
- *request = mRequestTemplateCache[templateId];
- return OK;
+ if (!mRequestTemplateCache[templateId].isEmpty()) {
+ *request = mRequestTemplateCache[templateId];
+ return OK;
+ }
}
camera_metadata_t *rawRequest;
status_t res = mInterface->constructDefaultRequestSettings(
(camera3_request_template_t) templateId, &rawRequest);
- if (res == BAD_VALUE) {
- ALOGI("%s: template %d is not supported on this camera device",
- __FUNCTION__, templateId);
- return res;
- } else if (res != OK) {
- CLOGE("Unable to construct request template %d: %s (%d)",
- templateId, strerror(-res), res);
- return res;
+
+ {
+ Mutex::Autolock l(mLock);
+ if (res == BAD_VALUE) {
+ ALOGI("%s: template %d is not supported on this camera device",
+ __FUNCTION__, templateId);
+ return res;
+ } else if (res != OK) {
+ CLOGE("Unable to construct request template %d: %s (%d)",
+ templateId, strerror(-res), res);
+ return res;
+ }
+
+ set_camera_metadata_vendor_id(rawRequest, mVendorTagId);
+ mRequestTemplateCache[templateId].acquire(rawRequest);
+
+ *request = mRequestTemplateCache[templateId];
}
-
- set_camera_metadata_vendor_id(rawRequest, mVendorTagId);
- mRequestTemplateCache[templateId].acquire(rawRequest);
-
- *request = mRequestTemplateCache[templateId];
return OK;
}
status_t Camera3Device::waitUntilDrained() {
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
+ nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
Mutex::Autolock l(mLock);
- return waitUntilDrainedLocked();
+ return waitUntilDrainedLocked(maxExpectedDuration);
}
-status_t Camera3Device::waitUntilDrainedLocked() {
+status_t Camera3Device::waitUntilDrainedLocked(nsecs_t maxExpectedDuration) {
switch (mStatus) {
case STATUS_UNINITIALIZED:
case STATUS_UNCONFIGURED:
@@ -1569,9 +1577,6 @@
SET_ERR_L("Unexpected status: %d",mStatus);
return INVALID_OPERATION;
}
-
- nsecs_t maxExpectedDuration = getExpectedInFlightDurationLocked();
-
ALOGV("%s: Camera %s: Waiting until idle (%" PRIi64 "ns)", __FUNCTION__, mId.string(),
maxExpectedDuration);
status_t res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
@@ -1590,11 +1595,10 @@
}
// Pause to reconfigure
-status_t Camera3Device::internalPauseAndWaitLocked() {
+status_t Camera3Device::internalPauseAndWaitLocked(nsecs_t maxExpectedDuration) {
mRequestThread->setPaused(true);
mPauseStateNotify = true;
- nsecs_t maxExpectedDuration = getExpectedInFlightDurationLocked();
ALOGV("%s: Camera %s: Internal wait until idle (% " PRIi64 " ns)", __FUNCTION__, mId.string(),
maxExpectedDuration);
status_t res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
@@ -2384,9 +2388,7 @@
}
}
- Mutex::Autolock ml(mLock);
mExpectedInflightDuration += maxExpectedDuration;
-
return OK;
}
@@ -2418,7 +2420,6 @@
mStatusTracker->markComponentIdle(mInFlightStatusId, Fence::NO_FENCE);
}
}
- Mutex::Autolock l(mLock);
mExpectedInflightDuration -= duration;
}
@@ -2500,6 +2501,7 @@
request.pendingOutputBuffers.size(), 0);
}
mInFlightMap.clear();
+ mExpectedInflightDuration = 0;
}
// Then return all inflight buffers not returned by HAL
@@ -4294,7 +4296,8 @@
return false;
}
-nsecs_t Camera3Device::getExpectedInFlightDurationLocked() {
+nsecs_t Camera3Device::getExpectedInFlightDuration() {
+ Mutex::Autolock al(mInFlightLock);
return mExpectedInflightDuration > kMinInflightDuration ?
mExpectedInflightDuration : kMinInflightDuration;
}