OSDN Git Service

camera3: Dump latest request sent with dumpsys
authorIgor Murashkin <iam@google.com>
Fri, 6 Sep 2013 23:55:14 +0000 (16:55 -0700)
committerIgor Murashkin <iam@google.com>
Sat, 7 Sep 2013 00:50:12 +0000 (17:50 -0700)
Bug: 10606535
Change-Id: I0dd5ca3e09f45701659ab9ebd3b51939a2f6e6ba

services/camera/libcameraservice/device3/Camera3Device.cpp
services/camera/libcameraservice/device3/Camera3Device.h

index 47321e0..2902340 100644 (file)
@@ -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,
index 6565048..0b3ad6e 100644 (file)
@@ -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;