Camera2: Improve threading safety
Merge mutex lock for accessing internal parameters with the parameter
structure, forcing a lock to be held before the parameters can be accessed.
Bug: 6243944
Change-Id: I86e44f395de0d80ff7c3ff3530f25b60015512d2
diff --git a/services/camera/libcameraservice/Camera2Client.h b/services/camera/libcameraservice/Camera2Client.h
index 83fe94e..3494114 100644
--- a/services/camera/libcameraservice/Camera2Client.h
+++ b/services/camera/libcameraservice/Camera2Client.h
@@ -89,7 +89,7 @@
// Ensures serialization between incoming ICamera calls
mutable Mutex mICameraLock;
- // The following must be called with mICamaeraLock already locked
+ // The following must be called with mICameraLock already locked
status_t setPreviewWindowLocked(const sp<IBinder>& binder,
sp<ANativeWindow> window);
@@ -97,9 +97,6 @@
void stopPreviewLocked();
status_t startPreviewLocked();
- // Mutex that must be locked before accessing mParameters, mParamsFlattened
- mutable Mutex mParamsLock;
- String8 mParamsFlattened;
// Current camera state; this is the contents of the CameraParameters object
// in a more-efficient format. The enum values are mostly based off the
// corresponding camera2 enums, not the camera1 strings. A few are defined
@@ -173,6 +170,59 @@
bool videoStabilization;
bool storeMetadataInBuffers;
+
+ String8 paramsFlattened;
+ };
+
+ class LockedParameters {
+ public:
+ class Key {
+ public:
+ Key(LockedParameters &p):
+ mParameters(p.mParameters),
+ mLockedParameters(p) {
+ mLockedParameters.mLock.lock();
+ }
+
+ ~Key() {
+ mLockedParameters.mLock.unlock();
+ }
+ Parameters &mParameters;
+ private:
+ // Disallow copying, default construction
+ Key();
+ Key(const Key &);
+ Key &operator=(const Key &);
+ LockedParameters &mLockedParameters;
+ };
+ class ReadKey {
+ public:
+ ReadKey(const LockedParameters &p):
+ mParameters(p.mParameters),
+ mLockedParameters(p) {
+ mLockedParameters.mLock.lock();
+ }
+
+ ~ReadKey() {
+ mLockedParameters.mLock.unlock();
+ }
+ const Parameters &mParameters;
+ private:
+ // Disallow copying, default construction
+ ReadKey();
+ ReadKey(const ReadKey &);
+ ReadKey &operator=(const ReadKey &);
+ const LockedParameters &mLockedParameters;
+ };
+
+ // Only use for dumping or other debugging
+ const Parameters &unsafeUnlock() {
+ return mParameters;
+ }
+ private:
+ Parameters mParameters;
+ mutable Mutex mLock;
+
} mParameters;
/** Camera device-related private members */
@@ -190,10 +240,9 @@
camera_metadata_t *mPreviewRequest;
sp<IBinder> mPreviewSurface;
sp<ANativeWindow> mPreviewWindow;
- // Update preview request based on mParameters
- status_t updatePreviewRequest();
- // Update preview stream based on mParameters
- status_t updatePreviewStream();
+
+ status_t updatePreviewRequest(const Parameters ¶ms);
+ status_t updatePreviewStream(const Parameters ¶ms);
/* Still image capture related members */
@@ -214,10 +263,9 @@
sp<Camera2Heap> mCaptureHeap;
// Handle captured image buffers
void onCaptureAvailable();
- // Update capture request based on mParameters
- status_t updateCaptureRequest();
- // Update capture stream based on mParameters
- status_t updateCaptureStream();
+
+ status_t updateCaptureRequest(const Parameters ¶ms);
+ status_t updateCaptureStream(const Parameters ¶ms);
/* Recording related members */
@@ -244,10 +292,9 @@
size_t mRecordingHeapHead, mRecordingHeapFree;
// Handle new recording image buffers
void onRecordingFrameAvailable();
- // Update recording request based on mParameters
- status_t updateRecordingRequest();
- // Update recording stream based on mParameters
- status_t updateRecordingStream();
+
+ status_t updateRecordingRequest(const Parameters ¶ms);
+ status_t updateRecordingStream(const Parameters ¶ms);
/** Camera2Device instance wrapping HAL2 entry */
@@ -293,7 +340,7 @@
status_t buildDefaultParameters();
// Update parameters all requests use, based on mParameters
- status_t updateRequestCommon(camera_metadata_t *request);
+ status_t updateRequestCommon(camera_metadata_t *request, const Parameters ¶ms);
// Update specific metadata entry with new values. Adds entry if it does not
// exist, which will invalidate sorting