Merge "Camera: Flush all state transitions before reconfigureCamera" into main am: 90940c49fb
Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/2742073
Change-Id: If08c48b3b50b9c39b3613977f8a599005cb05d33
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index a2d13f2..7e8b930 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -2339,6 +2339,9 @@
// deadlocks (http://b/143513518)
nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
+ // Make sure status tracker is flushed
+ mStatusTracker->flushPendingStates();
+
Mutex::Autolock l(mLock);
if (checkAbandonedStreamsLocked()) {
ALOGW("%s: Abandoned stream detected, session parameters can't be applied correctly!",
diff --git a/services/camera/libcameraservice/device3/StatusTracker.cpp b/services/camera/libcameraservice/device3/StatusTracker.cpp
index bd78e0a..f13109a 100644
--- a/services/camera/libcameraservice/device3/StatusTracker.cpp
+++ b/services/camera/libcameraservice/device3/StatusTracker.cpp
@@ -34,7 +34,8 @@
mParent(parent),
mNextComponentId(0),
mIdleFence(new Fence()),
- mDeviceState(IDLE) {
+ mDeviceState(IDLE),
+ mFlushed(true) {
}
StatusTracker::~StatusTracker() {
@@ -111,16 +112,33 @@
const sp<Fence>& componentFence) {
ALOGV("%s: Component %d is now %s", __FUNCTION__, id,
state == IDLE ? "idle" : "active");
- Mutex::Autolock l(mPendingLock);
- StateChange newState = {
- id,
- state,
- componentFence
- };
+ // If any component state changes, the status tracker is considered
+ // not flushed.
+ {
+ Mutex::Autolock l(mFlushLock);
+ mFlushed = false;
+ }
- mPendingChangeQueue.add(newState);
- mPendingChangeSignal.signal();
+ {
+ Mutex::Autolock l(mPendingLock);
+
+ StateChange newState = {
+ id,
+ state,
+ componentFence
+ };
+
+ mPendingChangeQueue.add(newState);
+ mPendingChangeSignal.signal();
+ }
+}
+
+void StatusTracker::flushPendingStates() {
+ Mutex::Autolock l(mFlushLock);
+ while (!mFlushed && isRunning()) {
+ mFlushCondition.waitRelative(mFlushLock, kWaitDuration);
+ }
}
void StatusTracker::requestExit() {
@@ -128,6 +146,7 @@
Thread::requestExit();
// Then exit any waits
mPendingChangeSignal.signal();
+ mFlushCondition.signal();
}
StatusTracker::ComponentState StatusTracker::getDeviceStateLocked() {
@@ -231,6 +250,17 @@
}
mStateTransitions.clear();
+ // After all pending changes are cleared and notified, mark the tracker
+ // as flushed.
+ {
+ Mutex::Autolock fl(mFlushLock);
+ Mutex::Autolock pl(mPendingLock);
+ if (mPendingChangeQueue.size() == 0) {
+ mFlushed = true;
+ mFlushCondition.signal();
+ }
+ }
+
if (waitForIdleFence) {
auto ret = mIdleFence->wait(kWaitDuration);
if (ret == NO_ERROR) {
diff --git a/services/camera/libcameraservice/device3/StatusTracker.h b/services/camera/libcameraservice/device3/StatusTracker.h
index 069bff6..fc65502 100644
--- a/services/camera/libcameraservice/device3/StatusTracker.h
+++ b/services/camera/libcameraservice/device3/StatusTracker.h
@@ -70,6 +70,10 @@
void dumpActiveComponents();
+ // Flush all pending states inflight in the tracker, and return upon
+ // completion.
+ void flushPendingStates();
+
virtual void requestExit();
protected:
@@ -113,6 +117,11 @@
// Current overall device state
ComponentState mDeviceState;
+ // For flushing all pending states transitions
+ bool mFlushed;
+ Mutex mFlushLock;
+ Condition mFlushCondition;
+
// Private to threadLoop
// Determine current overall device state