Loading services/camera/libcameraservice/device3/Camera3Device.cpp +61 −0 Original line number Diff line number Diff line Loading @@ -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()); Loading Loading @@ -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 */ Loading Loading @@ -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); } Loading Loading @@ -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, Loading services/camera/libcameraservice/device3/Camera3Device.h +17 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -174,6 +176,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. Loading Loading @@ -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(); Loading Loading @@ -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; Loading Loading
services/camera/libcameraservice/device3/Camera3Device.cpp +61 −0 Original line number Diff line number Diff line Loading @@ -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()); Loading Loading @@ -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 */ Loading Loading @@ -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); } Loading Loading @@ -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, Loading
services/camera/libcameraservice/device3/Camera3Device.h +17 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -174,6 +176,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. Loading Loading @@ -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(); Loading Loading @@ -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; Loading