summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--services/camera/libcameraservice/device3/Camera3Device.cpp61
-rw-r--r--services/camera/libcameraservice/device3/Camera3Device.h18
2 files changed, 78 insertions, 1 deletions
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 44ea739..b70a278 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -281,6 +281,14 @@ status_t Camera3Device::dump(int fd, const Vector<String16> &args) {
}
write(fd, lines.string(), lines.size());
+ {
+ lines = String8(" Last request sent:\n");
+ write(fd, lines.string(), lines.size());
+
+ CameraMetadata lastRequest = getLatestRequest();
+ lastRequest.dump(fd, /*verbosity*/2, /*indentation*/6);
+ }
+
if (mHal3Device != NULL) {
lines = String8(" HAL device dump:\n");
write(fd, lines.string(), lines.size());
@@ -1397,6 +1405,43 @@ void Camera3Device::notify(const camera3_notify_msg *msg) {
}
}
+CameraMetadata Camera3Device::getLatestRequest() {
+ ALOGV("%s", __FUNCTION__);
+
+ bool locked = false;
+
+ /**
+ * Why trylock instead of autolock?
+ *
+ * We want to be able to call this function from
+ * dumpsys, which often happens during deadlocks.
+ */
+ for (size_t i = 0; i < kDumpLockAttempts; ++i) {
+ if (mLock.tryLock() == NO_ERROR) {
+ locked = true;
+ break;
+ } else {
+ usleep(kDumpSleepDuration);
+ }
+ }
+
+ if (!locked) {
+ ALOGW("%s: Possible deadlock detected", __FUNCTION__);
+ }
+
+ CameraMetadata retVal;
+
+ if (mRequestThread != NULL) {
+ retVal = mRequestThread->getLatestRequest();
+ }
+
+ if (locked) {
+ mLock.unlock();
+ }
+
+ return retVal;
+}
+
/**
* RequestThread inner class methods
*/
@@ -1677,6 +1722,14 @@ bool Camera3Device::RequestThread::threadLoop() {
return false;
}
+ // Update the latest request sent to HAL
+ if (request.settings != NULL) { // Don't update them if they were unchanged
+ Mutex::Autolock al(mLatestRequestMutex);
+
+ camera_metadata_t* cloned = clone_camera_metadata(request.settings);
+ mLatestRequest.acquire(cloned);
+ }
+
if (request.settings != NULL) {
nextRequest->mSettings.unlock(request.settings);
}
@@ -1729,6 +1782,14 @@ bool Camera3Device::RequestThread::threadLoop() {
return true;
}
+CameraMetadata Camera3Device::RequestThread::getLatestRequest() const {
+ Mutex::Autolock al(mLatestRequestMutex);
+
+ ALOGV("RequestThread::%s", __FUNCTION__);
+
+ return mLatestRequest;
+}
+
void Camera3Device::RequestThread::cleanUpFailedRequest(
camera3_capture_request_t &request,
sp<CaptureRequest> &nextRequest,
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 6565048..0b3ad6e 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -127,6 +127,8 @@ class Camera3Device :
virtual status_t flush();
private:
+ static const size_t kDumpLockAttempts = 10;
+ static const size_t kDumpSleepDuration = 100000; // 0.10 sec
static const size_t kInFlightWarnLimit = 20;
static const nsecs_t kShutdownTimeout = 5000000000; // 5 sec
struct RequestTrigger;
@@ -175,6 +177,13 @@ class Camera3Device :
typedef List<sp<CaptureRequest> > RequestList;
/**
+ * Get the last request submitted to the hal by the request thread.
+ *
+ * Takes mLock.
+ */
+ virtual CameraMetadata getLatestRequest();
+
+ /**
* Lock-held version of waitUntilDrained. Will transition to IDLE on
* success.
*/
@@ -285,6 +294,12 @@ class Camera3Device :
*/
status_t waitUntilRequestProcessed(int32_t requestId, nsecs_t timeout);
+ /**
+ * Get the latest request that was sent to the HAL
+ * with process_capture_request.
+ */
+ CameraMetadata getLatestRequest() const;
+
protected:
virtual bool threadLoop();
@@ -343,10 +358,11 @@ class Camera3Device :
uint32_t mFrameNumber;
- Mutex mLatestRequestMutex;
+ mutable Mutex mLatestRequestMutex;
Condition mLatestRequestSignal;
// android.request.id for latest process_capture_request
int32_t mLatestRequestId;
+ CameraMetadata mLatestRequest;
typedef KeyedVector<uint32_t/*tag*/, RequestTrigger> TriggerMap;
Mutex mTriggerMutex;