Merge "Camera: Flush all state transitions before reconfigureCamera" into udc-qpr-dev
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 71e49fd..f4bfb52 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -2336,6 +2336,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 ea1f2c1..3a25877 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() {
@@ -227,6 +246,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();
+ }
+ }
+
return true;
}
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