diff options
-rw-r--r-- | services/camera/libcameraservice/device3/Camera3Device.cpp | 61 | ||||
-rw-r--r-- | services/camera/libcameraservice/device3/Camera3Device.h | 18 |
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; |