SurfaceFlinger: protect state members in Layer

Add proper locking to protect state members in Layer.
These members are accessed by both the main thread and binder.

Bug: 119481871
Test: SurfaceFlinger unit tests
Test: go/wm-smoke
Change-Id: I12d47711992e09c0677b77f7e1b36c1254b63a1b
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 6d0fdad..f4b3cdd 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -83,35 +83,35 @@
 
     mTransactionName = String8("TX - ") + mName;
 
-    mCurrentState.active_legacy.w = args.w;
-    mCurrentState.active_legacy.h = args.h;
-    mCurrentState.flags = layerFlags;
-    mCurrentState.active_legacy.transform.set(0, 0);
-    mCurrentState.crop_legacy.makeInvalid();
-    mCurrentState.requestedCrop_legacy = mCurrentState.crop_legacy;
-    mCurrentState.z = 0;
-    mCurrentState.color.a = 1.0f;
-    mCurrentState.layerStack = 0;
-    mCurrentState.sequence = 0;
-    mCurrentState.requested_legacy = mCurrentState.active_legacy;
-    mCurrentState.appId = 0;
-    mCurrentState.type = 0;
-    mCurrentState.active.w = UINT32_MAX;
-    mCurrentState.active.h = UINT32_MAX;
-    mCurrentState.active.transform.set(0, 0);
-    mCurrentState.transform = 0;
-    mCurrentState.transformToDisplayInverse = false;
-    mCurrentState.crop.makeInvalid();
-    mCurrentState.acquireFence = new Fence(-1);
-    mCurrentState.dataspace = ui::Dataspace::UNKNOWN;
-    mCurrentState.hdrMetadata.validTypes = 0;
-    mCurrentState.surfaceDamageRegion.clear();
-    mCurrentState.cornerRadius = 0.0f;
-    mCurrentState.api = -1;
-    mCurrentState.hasColorTransform = false;
+    mState.current.active_legacy.w = args.w;
+    mState.current.active_legacy.h = args.h;
+    mState.current.flags = layerFlags;
+    mState.current.active_legacy.transform.set(0, 0);
+    mState.current.crop_legacy.makeInvalid();
+    mState.current.requestedCrop_legacy = mState.current.crop_legacy;
+    mState.current.z = 0;
+    mState.current.color.a = 1.0f;
+    mState.current.layerStack = 0;
+    mState.current.sequence = 0;
+    mState.current.requested_legacy = mState.current.active_legacy;
+    mState.current.appId = 0;
+    mState.current.type = 0;
+    mState.current.active.w = UINT32_MAX;
+    mState.current.active.h = UINT32_MAX;
+    mState.current.active.transform.set(0, 0);
+    mState.current.transform = 0;
+    mState.current.transformToDisplayInverse = false;
+    mState.current.crop.makeInvalid();
+    mState.current.acquireFence = new Fence(-1);
+    mState.current.dataspace = ui::Dataspace::UNKNOWN;
+    mState.current.hdrMetadata.validTypes = 0;
+    mState.current.surfaceDamageRegion.clear();
+    mState.current.cornerRadius = 0.0f;
+    mState.current.api = -1;
+    mState.current.hasColorTransform = false;
 
     // drawing state & current state are identical
-    mDrawingState = mCurrentState;
+    mState.drawing = mState.current;
 
     CompositorTiming compositorTiming;
     args.flinger->getCompositorTiming(&compositorTiming);
@@ -148,14 +148,17 @@
 void Layer::onRemovedFromCurrentState() {
     mRemovedFromCurrentState = true;
 
-    // the layer is removed from SF mCurrentState to mLayersPendingRemoval
-    if (mCurrentState.zOrderRelativeOf != nullptr) {
-        sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote();
-        if (strongRelative != nullptr) {
-            strongRelative->removeZOrderRelative(this);
-            mFlinger->setTransactionFlags(eTraversalNeeded);
+    {
+        Mutex::Autolock lock(mStateMutex);
+        // the layer is removed from SF mState.current to mLayersPendingRemoval
+        if (mState.current.zOrderRelativeOf != nullptr) {
+            sp<Layer> strongRelative = mState.current.zOrderRelativeOf.promote();
+            if (strongRelative != nullptr) {
+                strongRelative->removeZOrderRelative(this);
+                mFlinger->setTransactionFlags(eTraversalNeeded);
+            }
+            mState.current.zOrderRelativeOf = nullptr;
         }
-        mCurrentState.zOrderRelativeOf = nullptr;
     }
 
     // Since we are no longer reachable from CurrentState SurfaceFlinger
@@ -294,21 +297,32 @@
 }
 
 Rect Layer::computeScreenBounds(bool reduceTransparentRegion) const {
+    Mutex::Autolock lock(mStateMutex);
     const State& s(getDrawingState());
     Region transparentRegion = reduceTransparentRegion ? getActiveTransparentRegion(s) : Region();
-    FloatRect bounds = computeBounds(transparentRegion);
-    ui::Transform t = getTransform();
+    FloatRect bounds = computeBoundsLocked(transparentRegion);
+    ui::Transform t = getTransformLocked();
     // Transform to screen space.
     bounds = t.transform(bounds);
     return Rect{bounds};
 }
 
 FloatRect Layer::computeBounds() const {
+    Mutex::Autolock lock(mStateMutex);
+    return computeBoundsLocked();
+}
+
+FloatRect Layer::computeBoundsLocked() const {
     const State& s(getDrawingState());
-    return computeBounds(getActiveTransparentRegion(s));
+    return computeBoundsLocked(getActiveTransparentRegion(s));
 }
 
 FloatRect Layer::computeBounds(const Region& activeTransparentRegion) const {
+    Mutex::Autolock lock(mStateMutex);
+    return computeBoundsLocked(activeTransparentRegion);
+}
+
+FloatRect Layer::computeBoundsLocked(const Region& activeTransparentRegion) const {
     const State& s(getDrawingState());
     Rect bounds = getCroppedBufferSize(s);
     FloatRect floatBounds = bounds.toFloatRect();
@@ -361,6 +375,7 @@
         // child bounds as well.
         ui::Transform t = s.active_legacy.transform;
         croppedBounds = t.transform(croppedBounds);
+        Mutex::Autolock lock(p->mStateMutex);
         croppedBounds = p->cropChildBounds(croppedBounds);
         croppedBounds = t.inverse().transform(croppedBounds);
     }
@@ -388,8 +403,8 @@
     // if there are no window scaling involved, this operation will map to full
     // pixels in the buffer.
 
-    FloatRect activeCropFloat = computeBounds();
-    ui::Transform t = getTransform();
+    FloatRect activeCropFloat = computeBoundsLocked();
+    ui::Transform t = getTransformLocked();
     // Transform to screen space.
     activeCropFloat = t.transform(activeCropFloat);
     activeCropFloat = activeCropFloat.intersect(display->getViewport().toFloatRect());
@@ -439,7 +454,7 @@
     // which means using the inverse of the current transform set on the
     // SurfaceFlingerConsumer.
     uint32_t invTransform = mCurrentTransform;
-    if (getTransformToDisplayInverse()) {
+    if (getTransformToDisplayInverseLocked()) {
         /*
          * the code below applies the primary display's inverse transform to the
          * buffer
@@ -490,6 +505,7 @@
 }
 
 void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) {
+    Mutex::Autolock lock(mStateMutex);
     const auto displayId = display->getId();
     LOG_ALWAYS_FATAL_IF(!displayId);
     RETURN_IF_NO_HWC_LAYER(*displayId);
@@ -498,7 +514,7 @@
     // enable this layer
     hwcInfo.forceClientComposition = false;
 
-    if (isSecure() && !display->isSecure()) {
+    if (isSecureLocked() && !display->isSecure()) {
         hwcInfo.forceClientComposition = true;
     }
 
@@ -508,7 +524,7 @@
     const State& s(getDrawingState());
     const Rect bufferSize = getBufferSize(s);
     auto blendMode = HWC2::BlendMode::None;
-    if (!isOpaque(s) || getAlpha() != 1.0f) {
+    if (!isOpaque(s) || getAlphaLocked() != 1.0f) {
         blendMode =
                 mPremultipliedAlpha ? HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
     }
@@ -523,7 +539,7 @@
     // apply the layer's transform, followed by the display's global transform
     // here we're guaranteed that the layer's transform preserves rects
     Region activeTransparentRegion(getActiveTransparentRegion(s));
-    ui::Transform t = getTransform();
+    ui::Transform t = getTransformLocked();
     Rect activeCrop = getCrop(s);
     if (!activeCrop.isEmpty() && bufferSize.isValid()) {
         activeCrop = t.transform(activeCrop);
@@ -551,7 +567,7 @@
 
     // computeBounds returns a FloatRect to provide more accuracy during the
     // transformation. We then round upon constructing 'frame'.
-    Rect frame{t.transform(computeBounds(activeTransparentRegion))};
+    Rect frame{t.transform(computeBoundsLocked(activeTransparentRegion))};
     if (!frame.intersect(display->getViewport(), &frame)) {
         frame.clear();
     }
@@ -579,7 +595,7 @@
     }
     getBE().compositionInfo.hwc.sourceCrop = sourceCrop;
 
-    float alpha = static_cast<float>(getAlpha());
+    float alpha = static_cast<float>(getAlphaLocked());
     error = hwcLayer->setPlaneAlpha(alpha);
     ALOGE_IF(error != HWC2::Error::None,
              "[%s] Failed to set plane alpha %.3f: "
@@ -596,6 +612,7 @@
     int appId = s.appId;
     sp<Layer> parent = mDrawingParent.promote();
     if (parent.get()) {
+        Mutex::Autolock lock(parent->mStateMutex);
         auto& parentState = parent->getDrawingState();
         if (parentState.type >= 0 || parentState.appId >= 0) {
             type = parentState.type;
@@ -621,7 +638,7 @@
     const ui::Transform bufferOrientation(mCurrentTransform);
     ui::Transform transform(tr * t * bufferOrientation);
 
-    if (getTransformToDisplayInverse()) {
+    if (getTransformToDisplayInverseLocked()) {
         /*
          * the code below applies the primary display's inverse transform to the
          * buffer
@@ -671,6 +688,7 @@
 }
 
 void Layer::updateCursorPosition(const sp<const DisplayDevice>& display) {
+    Mutex::Autolock lock(mStateMutex);
     const auto displayId = display->getId();
     LOG_ALWAYS_FATAL_IF(!displayId);
     if (!hasHwcLayer(*displayId) || getCompositionType(displayId) != HWC2::Composition::Cursor) {
@@ -685,7 +703,7 @@
     Rect win = getCroppedBufferSize(s);
     // Subtract the transparent region and snap to the bounds
     Rect bounds = reduce(win, getActiveTransparentRegion(s));
-    Rect frame(getTransform().transform(bounds));
+    Rect frame(getTransformLocked().transform(bounds));
     frame.intersect(display->getViewport(), &frame);
     auto& displayTransform = display->getTransform();
     auto position = displayTransform.transform(frame);
@@ -715,6 +733,7 @@
 void Layer::clearWithOpenGL(const RenderArea& renderArea, float red, float green, float blue,
                             float alpha) const {
     auto& engine(mFlinger->getRenderEngine());
+    Mutex::Autolock lock(mStateMutex);
     computeGeometry(renderArea, getBE().mMesh, false);
     engine.setupFillWithColor(red, green, blue, alpha);
     engine.drawMesh(getBE().mMesh);
@@ -799,14 +818,14 @@
                             renderengine::Mesh& mesh,
                             bool useIdentityTransform) const {
     const ui::Transform renderAreaTransform(renderArea.getTransform());
-    FloatRect win = computeBounds();
+    FloatRect win = computeBoundsLocked();
 
     vec2 lt = vec2(win.left, win.top);
     vec2 lb = vec2(win.left, win.bottom);
     vec2 rb = vec2(win.right, win.bottom);
     vec2 rt = vec2(win.right, win.top);
 
-    ui::Transform layerTransform = getTransform();
+    ui::Transform layerTransform = getTransformLocked();
     if (!useIdentityTransform) {
         lt = layerTransform.transform(lt);
         lb = layerTransform.transform(lb);
@@ -822,7 +841,12 @@
 }
 
 bool Layer::isSecure() const {
-    const State& s(mDrawingState);
+    Mutex::Autolock lock(mStateMutex);
+    return isSecureLocked();
+}
+
+bool Layer::isSecureLocked() const {
+    const State& s(mState.drawing);
     return (s.flags & layer_state_t::eLayerSecure);
 }
 
@@ -850,9 +874,13 @@
 // ----------------------------------------------------------------------------
 // transaction
 // ----------------------------------------------------------------------------
-
 void Layer::pushPendingState() {
-    if (!mCurrentState.modified) {
+    Mutex::Autolock lock(mStateMutex);
+    pushPendingStateLocked();
+}
+
+void Layer::pushPendingStateLocked() {
+    if (!mState.current.modified) {
         return;
     }
 
@@ -860,22 +888,22 @@
     // point and send it to the remote layer.
     // We don't allow installing sync points after we are removed from the current state
     // as we won't be able to signal our end.
-    if (mCurrentState.barrierLayer_legacy != nullptr && !isRemovedFromCurrentState()) {
-        sp<Layer> barrierLayer = mCurrentState.barrierLayer_legacy.promote();
+    if (mState.current.barrierLayer_legacy != nullptr && !isRemovedFromCurrentState()) {
+        sp<Layer> barrierLayer = mState.current.barrierLayer_legacy.promote();
         if (barrierLayer == nullptr) {
             ALOGE("[%s] Unable to promote barrier Layer.", mName.string());
             // If we can't promote the layer we are intended to wait on,
             // then it is expired or otherwise invalid. Allow this transaction
             // to be applied as per normal (no synchronization).
-            mCurrentState.barrierLayer_legacy = nullptr;
+            mState.current.barrierLayer_legacy = nullptr;
         } else {
-            auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.frameNumber_legacy);
+            auto syncPoint = std::make_shared<SyncPoint>(mState.current.frameNumber_legacy);
             if (barrierLayer->addSyncPoint(syncPoint)) {
                 mRemoteSyncPoints.push_back(std::move(syncPoint));
             } else {
                 // We already missed the frame we're supposed to synchronize
                 // on, so go ahead and apply the state update
-                mCurrentState.barrierLayer_legacy = nullptr;
+                mState.current.barrierLayer_legacy = nullptr;
             }
         }
 
@@ -883,21 +911,21 @@
         setTransactionFlags(eTransactionNeeded);
         mFlinger->setTransactionFlags(eTraversalNeeded);
     }
-    mPendingStates.push_back(mCurrentState);
-    ATRACE_INT(mTransactionName.string(), mPendingStates.size());
+    mState.pending.push_back(mState.current);
+    ATRACE_INT(mTransactionName.string(), mState.pending.size());
 }
 
 void Layer::popPendingState(State* stateToCommit) {
-    *stateToCommit = mPendingStates[0];
+    *stateToCommit = mState.pending[0];
 
-    mPendingStates.removeAt(0);
-    ATRACE_INT(mTransactionName.string(), mPendingStates.size());
+    mState.pending.removeAt(0);
+    ATRACE_INT(mTransactionName.string(), mState.pending.size());
 }
 
 bool Layer::applyPendingStates(State* stateToCommit) {
     bool stateUpdateAvailable = false;
-    while (!mPendingStates.empty()) {
-        if (mPendingStates[0].barrierLayer_legacy != nullptr) {
+    while (!mState.pending.empty()) {
+        if (mState.pending[0].barrierLayer_legacy != nullptr) {
             if (mRemoteSyncPoints.empty()) {
                 // If we don't have a sync point for this, apply it anyway. It
                 // will be visually wrong, but it should keep us from getting
@@ -909,7 +937,7 @@
             }
 
             if (mRemoteSyncPoints.front()->getFrameNumber() !=
-                mPendingStates[0].frameNumber_legacy) {
+                mState.pending[0].frameNumber_legacy) {
                 ALOGE("[%s] Unexpected sync point frame number found", mName.string());
 
                 // Signal our end of the sync point and then dispose of it
@@ -937,12 +965,12 @@
 
     // If we still have pending updates, wake SurfaceFlinger back up and point
     // it at this layer so we can process them
-    if (!mPendingStates.empty()) {
+    if (!mState.pending.empty()) {
         setTransactionFlags(eTransactionNeeded);
         mFlinger->setTransactionFlags(eTraversalNeeded);
     }
 
-    mCurrentState.modified = false;
+    mState.current.modified = false;
     return stateUpdateAvailable;
 }
 
@@ -1039,7 +1067,8 @@
         return 0;
     }
 
-    pushPendingState();
+    Mutex::Autolock lock(mStateMutex);
+    pushPendingStateLocked();
     State c = getCurrentState();
     if (!applyPendingStates(&c)) {
         return 0;
@@ -1071,49 +1100,60 @@
         clearSyncPoints();
     }
 
-    if (mCurrentState.inputInfoChanged) {
+    if (mState.current.inputInfoChanged) {
         flags |= eInputInfoChanged;
-        mCurrentState.inputInfoChanged = false;
+        mState.current.inputInfoChanged = false;
     }
 
     // Commit the transaction
     commitTransaction(c);
-    mCurrentState.callbackHandles = {};
+    mState.current.callbackHandles = {};
     return flags;
 }
 
 void Layer::commitTransaction(const State& stateToCommit) {
-    mDrawingState = stateToCommit;
+    mState.drawing = stateToCommit;
+}
+
+uint32_t Layer::getTransactionFlags() const {
+    Mutex::Autolock lock(mStateMutex);
+    return mState.transactionFlags;
 }
 
 uint32_t Layer::getTransactionFlags(uint32_t flags) {
-    return mTransactionFlags.fetch_and(~flags) & flags;
+    Mutex::Autolock lock(mStateMutex);
+    uint32_t and_flags = mState.transactionFlags & flags;
+    mState.transactionFlags &= ~flags;
+    return and_flags;
 }
 
 uint32_t Layer::setTransactionFlags(uint32_t flags) {
-    return mTransactionFlags.fetch_or(flags);
+    uint32_t old_flags = mState.transactionFlags;
+    mState.transactionFlags |= flags;
+    return old_flags;
 }
 
 bool Layer::setPosition(float x, float y, bool immediate) {
-    if (mCurrentState.requested_legacy.transform.tx() == x &&
-        mCurrentState.requested_legacy.transform.ty() == y)
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.requested_legacy.transform.tx() == x &&
+        mState.current.requested_legacy.transform.ty() == y)
         return false;
-    mCurrentState.sequence++;
+    mState.current.sequence++;
 
     // We update the requested and active position simultaneously because
     // we want to apply the position portion of the transform matrix immediately,
     // but still delay scaling when resizing a SCALING_MODE_FREEZE layer.
-    mCurrentState.requested_legacy.transform.set(x, y);
+    mState.current.requested_legacy.transform.set(x, y);
     if (immediate && !mFreezeGeometryUpdates) {
         // Here we directly update the active state
         // unlike other setters, because we store it within
         // the transform, but use different latching rules.
         // b/38182305
-        mCurrentState.active_legacy.transform.set(x, y);
+        mState.current.active_legacy.transform.set(x, y);
     }
     mFreezeGeometryUpdates = mFreezeGeometryUpdates || !immediate;
 
-    mCurrentState.modified = true;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
@@ -1146,38 +1186,44 @@
 }
 
 bool Layer::setLayer(int32_t z) {
-    if (mCurrentState.z == z && !usingRelativeZ(LayerVector::StateSet::Current)) return false;
-    mCurrentState.sequence++;
-    mCurrentState.z = z;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.z == z && !usingRelativeZLocked(LayerVector::StateSet::Current))
+        return false;
+
+    mState.current.sequence++;
+    mState.current.z = z;
+    mState.current.modified = true;
 
     // Discard all relative layering.
-    if (mCurrentState.zOrderRelativeOf != nullptr) {
-        sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote();
+    if (mState.current.zOrderRelativeOf != nullptr) {
+        sp<Layer> strongRelative = mState.current.zOrderRelativeOf.promote();
         if (strongRelative != nullptr) {
             strongRelative->removeZOrderRelative(this);
         }
-        mCurrentState.zOrderRelativeOf = nullptr;
+        mState.current.zOrderRelativeOf = nullptr;
     }
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 void Layer::removeZOrderRelative(const wp<Layer>& relative) {
-    mCurrentState.zOrderRelatives.remove(relative);
-    mCurrentState.sequence++;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.zOrderRelatives.remove(relative);
+    mState.current.sequence++;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
 }
 
 void Layer::addZOrderRelative(const wp<Layer>& relative) {
-    mCurrentState.zOrderRelatives.add(relative);
-    mCurrentState.modified = true;
-    mCurrentState.sequence++;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.zOrderRelatives.add(relative);
+    mState.current.modified = true;
+    mState.current.sequence++;
     setTransactionFlags(eTransactionNeeded);
 }
 
 bool Layer::setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ) {
+    Mutex::Autolock lock(mStateMutex);
     sp<Handle> handle = static_cast<Handle*>(relativeToHandle.get());
     if (handle == nullptr) {
         return false;
@@ -1187,20 +1233,20 @@
         return false;
     }
 
-    if (mCurrentState.z == relativeZ && usingRelativeZ(LayerVector::StateSet::Current) &&
-            mCurrentState.zOrderRelativeOf == relative) {
+    if (mState.current.z == relativeZ && usingRelativeZLocked(LayerVector::StateSet::Current) &&
+        mState.current.zOrderRelativeOf == relative) {
         return false;
     }
 
-    mCurrentState.sequence++;
-    mCurrentState.modified = true;
-    mCurrentState.z = relativeZ;
+    mState.current.sequence++;
+    mState.current.modified = true;
+    mState.current.z = relativeZ;
 
-    auto oldZOrderRelativeOf = mCurrentState.zOrderRelativeOf.promote();
+    auto oldZOrderRelativeOf = mState.current.zOrderRelativeOf.promote();
     if (oldZOrderRelativeOf != nullptr) {
         oldZOrderRelativeOf->removeZOrderRelative(this);
     }
-    mCurrentState.zOrderRelativeOf = relative;
+    mState.current.zOrderRelativeOf = relative;
     relative->addZOrderRelative(this);
 
     setTransactionFlags(eTransactionNeeded);
@@ -1209,48 +1255,51 @@
 }
 
 bool Layer::setSize(uint32_t w, uint32_t h) {
-    if (mCurrentState.requested_legacy.w == w && mCurrentState.requested_legacy.h == h)
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.requested_legacy.w == w && mState.current.requested_legacy.h == h)
         return false;
-    mCurrentState.requested_legacy.w = w;
-    mCurrentState.requested_legacy.h = h;
-    mCurrentState.modified = true;
+    mState.current.requested_legacy.w = w;
+    mState.current.requested_legacy.h = h;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
 
     // record the new size, from this point on, when the client request
     // a buffer, it'll get the new size.
-    setDefaultBufferSize(mCurrentState.requested_legacy.w, mCurrentState.requested_legacy.h);
+    setDefaultBufferSize(mState.current.requested_legacy.w, mState.current.requested_legacy.h);
     return true;
 }
 bool Layer::setAlpha(float alpha) {
-    if (mCurrentState.color.a == alpha) return false;
-    mCurrentState.sequence++;
-    mCurrentState.color.a = alpha;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.color.a == alpha) return false;
+    mState.current.sequence++;
+    mState.current.color.a = alpha;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setColor(const half3& color) {
-    if (color.r == mCurrentState.color.r && color.g == mCurrentState.color.g &&
-        color.b == mCurrentState.color.b)
+    Mutex::Autolock lock(mStateMutex);
+    if (color.r == mState.current.color.r && color.g == mState.current.color.g &&
+        color.b == mState.current.color.b)
         return false;
 
-    mCurrentState.sequence++;
-    mCurrentState.color.r = color.r;
-    mCurrentState.color.g = color.g;
-    mCurrentState.color.b = color.b;
-    mCurrentState.modified = true;
+    mState.current.sequence++;
+    mState.current.color.r = color.r;
+    mState.current.color.g = color.g;
+    mState.current.color.b = color.b;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setCornerRadius(float cornerRadius) {
-    if (mCurrentState.cornerRadius == cornerRadius)
-        return false;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.cornerRadius == cornerRadius) return false;
 
-    mCurrentState.sequence++;
-    mCurrentState.cornerRadius = cornerRadius;
-    mCurrentState.modified = true;
+    mState.current.sequence++;
+    mState.current.cornerRadius = cornerRadius;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
@@ -1264,45 +1313,50 @@
         ALOGW("Attempt to set rotation matrix without permission ACCESS_SURFACE_FLINGER ignored");
         return false;
     }
-    mCurrentState.sequence++;
-    mCurrentState.requested_legacy.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx,
-                                                 matrix.dsdy);
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.sequence++;
+    mState.current.requested_legacy.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx,
+                                                  matrix.dsdy);
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setTransparentRegionHint(const Region& transparent) {
-    mCurrentState.requestedTransparentRegion_legacy = transparent;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.requestedTransparentRegion_legacy = transparent;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 bool Layer::setFlags(uint8_t flags, uint8_t mask) {
-    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
-    if (mCurrentState.flags == newFlags) return false;
-    mCurrentState.sequence++;
-    mCurrentState.flags = newFlags;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    const uint32_t newFlags = (mState.current.flags & ~mask) | (flags & mask);
+    if (mState.current.flags == newFlags) return false;
+    mState.current.sequence++;
+    mState.current.flags = newFlags;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setCrop_legacy(const Rect& crop, bool immediate) {
-    if (mCurrentState.requestedCrop_legacy == crop) return false;
-    mCurrentState.sequence++;
-    mCurrentState.requestedCrop_legacy = crop;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.requestedCrop_legacy == crop) return false;
+    mState.current.sequence++;
+    mState.current.requestedCrop_legacy = crop;
     if (immediate && !mFreezeGeometryUpdates) {
-        mCurrentState.crop_legacy = crop;
+        mState.current.crop_legacy = crop;
     }
     mFreezeGeometryUpdates = mFreezeGeometryUpdates || !immediate;
 
-    mCurrentState.modified = true;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setOverrideScalingMode(int32_t scalingMode) {
+    Mutex::Autolock lock(mStateMutex);
     if (scalingMode == mOverrideScalingMode) return false;
     mOverrideScalingMode = scalingMode;
     setTransactionFlags(eTransactionNeeded);
@@ -1310,22 +1364,29 @@
 }
 
 void Layer::setInfo(int32_t type, int32_t appId) {
-    mCurrentState.appId = appId;
-    mCurrentState.type = type;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.appId = appId;
+    mState.current.type = type;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
 }
 
 bool Layer::setLayerStack(uint32_t layerStack) {
-    if (mCurrentState.layerStack == layerStack) return false;
-    mCurrentState.sequence++;
-    mCurrentState.layerStack = layerStack;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.layerStack == layerStack) return false;
+    mState.current.sequence++;
+    mState.current.layerStack = layerStack;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 uint32_t Layer::getLayerStack() const {
+    Mutex::Autolock lock(mStateMutex);
+    return getLayerStackLocked();
+}
+
+uint32_t Layer::getLayerStackLocked() const {
     auto p = mDrawingParent.promote();
     if (p == nullptr) {
         return getDrawingState().layerStack;
@@ -1334,15 +1395,16 @@
 }
 
 void Layer::deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber) {
-    mCurrentState.barrierLayer_legacy = barrierLayer;
-    mCurrentState.frameNumber_legacy = frameNumber;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.barrierLayer_legacy = barrierLayer;
+    mState.current.frameNumber_legacy = frameNumber;
     // We don't set eTransactionNeeded, because just receiving a deferral
     // request without any other state updates shouldn't actually induce a delay
-    mCurrentState.modified = true;
-    pushPendingState();
-    mCurrentState.barrierLayer_legacy = nullptr;
-    mCurrentState.frameNumber_legacy = 0;
-    mCurrentState.modified = false;
+    mState.current.modified = true;
+    pushPendingStateLocked();
+    mState.current.barrierLayer_legacy = nullptr;
+    mState.current.frameNumber_legacy = 0;
+    mState.current.modified = false;
 }
 
 void Layer::deferTransactionUntil_legacy(const sp<IBinder>& barrierHandle, uint64_t frameNumber) {
@@ -1355,7 +1417,8 @@
 // ----------------------------------------------------------------------------
 
 bool Layer::isHiddenByPolicy() const {
-    const State& s(mDrawingState);
+    Mutex::Autolock lock(mStateMutex);
+    const State& s(mState.drawing);
     const auto& parent = mDrawingParent.promote();
     if (parent != nullptr && parent->isHiddenByPolicy()) {
         return true;
@@ -1400,6 +1463,7 @@
 
 // TODO(marissaw): add new layer state info to layer debugging
 LayerDebugInfo Layer::getLayerDebugInfo() const {
+    Mutex::Autolock lock(mStateMutex);
     LayerDebugInfo info;
     const State& ds = getDrawingState();
     info.mName = getName();
@@ -1409,7 +1473,7 @@
     info.mTransparentRegion = ds.activeTransparentRegion_legacy;
     info.mVisibleRegion = visibleRegion;
     info.mSurfaceDamageRegion = surfaceDamageRegion;
-    info.mLayerStack = getLayerStack();
+    info.mLayerStack = getLayerStackLocked();
     info.mX = ds.active_legacy.transform.tx();
     info.mY = ds.active_legacy.transform.ty();
     info.mZ = ds.z;
@@ -1445,6 +1509,13 @@
     return info;
 }
 
+std::tuple<uint32_t, int32_t> Layer::getLayerStackAndZ(StateSet stateSet) {
+    Mutex::Autolock lock(mStateMutex);
+    const State& state = (stateSet == StateSet::Current) ? mState.current : mState.drawing;
+
+    return {state.layerStack, state.z};
+}
+
 void Layer::miniDumpHeader(std::string& result) {
     result.append("-------------------------------");
     result.append("-------------------------------");
@@ -1461,6 +1532,7 @@
 }
 
 void Layer::miniDump(std::string& result, DisplayId displayId) const {
+    Mutex::Autolock lock(mStateMutex);
     if (!hasHwcLayer(displayId)) {
         return;
     }
@@ -1589,6 +1661,7 @@
     }
 
     if (attachChildren()) {
+        Mutex::Autolock lock(mStateMutex);
         setTransactionFlags(eTransactionNeeded);
     }
     for (const sp<Layer>& child : mCurrentChildren) {
@@ -1639,6 +1712,7 @@
         client->updateParent(newParent);
     }
 
+    Mutex::Autolock lock(mStateMutex);
     if (mLayerDetached) {
         mLayerDetached = false;
         setTransactionFlags(eTransactionNeeded);
@@ -1682,18 +1756,24 @@
 bool Layer::setColorTransform(const mat4& matrix) {
     static const mat4 identityMatrix = mat4();
 
-    if (mCurrentState.colorTransform == matrix) {
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.colorTransform == matrix) {
         return false;
     }
-    ++mCurrentState.sequence;
-    mCurrentState.colorTransform = matrix;
-    mCurrentState.hasColorTransform = matrix != identityMatrix;
-    mCurrentState.modified = true;
+    ++mState.current.sequence;
+    mState.current.colorTransform = matrix;
+    mState.current.hasColorTransform = matrix != identityMatrix;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 mat4 Layer::getColorTransform() const {
+    Mutex::Autolock lock(mStateMutex);
+    return getColorTransformLocked();
+}
+
+mat4 Layer::getColorTransformLocked() const {
     mat4 colorTransform = mat4(getDrawingState().colorTransform);
     if (sp<Layer> parent = mDrawingParent.promote(); parent != nullptr) {
         colorTransform = parent->getColorTransform() * colorTransform;
@@ -1702,6 +1782,7 @@
 }
 
 bool Layer::hasColorTransform() const {
+    Mutex::Autolock lock(mStateMutex);
     bool hasColorTransform = getDrawingState().hasColorTransform;
     if (sp<Layer> parent = mDrawingParent.promote(); parent != nullptr) {
         hasColorTransform = hasColorTransform || parent->hasColorTransform();
@@ -1732,12 +1813,18 @@
 }
 
 int32_t Layer::getZ() const {
-    return mDrawingState.z;
+    Mutex::Autolock lock(mStateMutex);
+    return mState.drawing.z;
 }
 
 bool Layer::usingRelativeZ(LayerVector::StateSet stateSet) {
+    Mutex::Autolock lock(mStateMutex);
+    return usingRelativeZLocked(stateSet);
+}
+
+bool Layer::usingRelativeZLocked(LayerVector::StateSet stateSet) {
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
-    const State& state = useDrawing ? mDrawingState : mCurrentState;
+    const State& state = useDrawing ? mState.drawing : mState.current;
     return state.zOrderRelativeOf != nullptr;
 }
 
@@ -1747,7 +1834,7 @@
                         "makeTraversalList received invalid stateSet");
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
     const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
-    const State& state = useDrawing ? mDrawingState : mCurrentState;
+    const State& state = useDrawing ? mState.drawing : mState.current;
 
     if (state.zOrderRelatives.size() == 0) {
         *outSkipRelativeZUsers = true;
@@ -1763,7 +1850,7 @@
     }
 
     for (const sp<Layer>& child : children) {
-        const State& childState = useDrawing ? child->mDrawingState : child->mCurrentState;
+        const State& childState = useDrawing ? child->mState.drawing : child->mState.current;
         if (childState.zOrderRelativeOf != nullptr) {
             continue;
         }
@@ -1802,7 +1889,6 @@
     visitor(this);
     for (; i < list.size(); i++) {
         const auto& relative = list[i];
-
         if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
             continue;
         }
@@ -1850,7 +1936,7 @@
                         "makeTraversalList received invalid stateSet");
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
     const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
-    const State& state = useDrawing ? mDrawingState : mCurrentState;
+    const State& state = useDrawing ? mState.drawing : mState.current;
 
     LayerVector traverse(stateSet);
     for (const wp<Layer>& weakRelative : state.zOrderRelatives) {
@@ -1863,7 +1949,7 @@
     }
 
     for (const sp<Layer>& child : children) {
-        const State& childState = useDrawing ? child->mDrawingState : child->mCurrentState;
+        const State& childState = useDrawing ? child->mState.drawing : child->mState.current;
         // If a layer has a relativeOf layer, only ignore if the layer it's relative to is a
         // descendent of the top most parent of the tree. If it's not a descendent, then just add
         // the child here since it won't be added later as a relative.
@@ -1920,10 +2006,16 @@
 }
 
 ui::Transform Layer::getTransform() const {
+    Mutex::Autolock lock(mStateMutex);
+    return getTransformLocked();
+}
+
+ui::Transform Layer::getTransformLocked() const {
     ui::Transform t;
     const auto& p = mDrawingParent.promote();
     if (p != nullptr) {
-        t = p->getTransform();
+        Mutex::Autolock lock(p->mStateMutex);
+        t = p->getTransformLocked();
 
         // If the parent is not using NATIVE_WINDOW_SCALING_MODE_FREEZE (e.g.
         // it isFixedSize) then there may be additional scaling not accounted
@@ -1951,18 +2043,27 @@
 }
 
 half Layer::getAlpha() const {
-    const auto& p = mDrawingParent.promote();
+    Mutex::Autolock lock(mStateMutex);
+    return getAlphaLocked();
+}
 
+half Layer::getAlphaLocked() const {
+    const auto& p = mDrawingParent.promote();
     half parentAlpha = (p != nullptr) ? p->getAlpha() : 1.0_hf;
     return parentAlpha * getDrawingState().color.a;
 }
 
 half4 Layer::getColor() const {
     const half4 color(getDrawingState().color);
-    return half4(color.r, color.g, color.b, getAlpha());
+    return half4(color.r, color.g, color.b, getAlphaLocked());
 }
 
 Layer::RoundedCornerState Layer::getRoundedCornerState() const {
+    Mutex::Autolock lock(mStateMutex);
+    return getRoundedCornerStateLocked();
+}
+
+Layer::RoundedCornerState Layer::getRoundedCornerStateLocked() const {
     const auto& p = mDrawingParent.promote();
     if (p != nullptr) {
         RoundedCornerState parentState = p->getRoundedCornerState();
@@ -1979,7 +2080,7 @@
         }
     }
     const float radius = getDrawingState().cornerRadius;
-    return radius > 0 ? RoundedCornerState(computeBounds(), radius) : RoundedCornerState();
+    return radius > 0 ? RoundedCornerState(computeBoundsLocked(), radius) : RoundedCornerState();
 }
 
 void Layer::commitChildList() {
@@ -1992,19 +2093,21 @@
 }
 
 void Layer::setInputInfo(const InputWindowInfo& info) {
-    mCurrentState.inputInfo = info;
-    mCurrentState.modified = true;
-    mCurrentState.inputInfoChanged = true;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.inputInfo = info;
+    mState.current.modified = true;
+    mState.current.inputInfoChanged = true;
     setTransactionFlags(eTransactionNeeded);
 }
 
 void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) {
+    Mutex::Autolock lock(mStateMutex);
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
     const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
-    const State& state = useDrawing ? mDrawingState : mCurrentState;
+    const State& state = useDrawing ? mState.drawing : mState.current;
 
     ui::Transform requestedTransform = state.active_legacy.transform;
-    ui::Transform transform = getTransform();
+    ui::Transform transform = getTransformLocked();
 
     layerInfo->set_id(sequence);
     layerInfo->set_name(getName().c_str());
@@ -2026,7 +2129,7 @@
     LayerProtoHelper::writeToProto(visibleRegion, layerInfo->mutable_visible_region());
     LayerProtoHelper::writeToProto(surfaceDamageRegion, layerInfo->mutable_damage_region());
 
-    layerInfo->set_layer_stack(getLayerStack());
+    layerInfo->set_layer_stack(getLayerStackLocked());
     layerInfo->set_z(state.z);
 
     PositionProto* position = layerInfo->mutable_position();
@@ -2042,7 +2145,7 @@
     size->set_h(state.active_legacy.h);
 
     LayerProtoHelper::writeToProto(state.crop_legacy, layerInfo->mutable_crop());
-    layerInfo->set_corner_radius(getRoundedCornerState().radius);
+    layerInfo->set_corner_radius(getRoundedCornerStateLocked().radius);
 
     layerInfo->set_is_opaque(isOpaque(state));
     layerInfo->set_invalidate(contentDirty);
@@ -2083,7 +2186,7 @@
     layerInfo->set_curr_frame(mCurrentFrameNumber);
     layerInfo->set_effective_scaling_mode(getEffectiveScalingMode());
 
-    for (const auto& pendingState : mPendingStates) {
+    for (const auto& pendingState : mState.pending) {
         auto barrierLayer = pendingState.barrierLayer_legacy.promote();
         if (barrierLayer != nullptr) {
             BarrierLayerProto* barrierLayerProto = layerInfo->add_barrier_layer();
@@ -2127,19 +2230,25 @@
 }
 
 InputWindowInfo Layer::fillInputInfo(const Rect& screenBounds) {
-    InputWindowInfo info = mDrawingState.inputInfo;
+    InputWindowInfo info;
+    ui::Transform t;
+    Rect layerBounds;
+    {
+        Mutex::Autolock lock(mStateMutex);
+        info = mState.drawing.inputInfo;
+        t = getTransformLocked();
+        const float xScale = t.sx();
+        const float yScale = t.sy();
+        if (xScale != 1.0f || yScale != 1.0f) {
+            info.windowXScale *= 1.0f / xScale;
+            info.windowYScale *= 1.0f / yScale;
+            info.touchableRegion.scaleSelf(xScale, yScale);
+        }
 
-    ui::Transform t = getTransform();
-    const float xScale = t.sx();
-    const float yScale = t.sy();
-    if (xScale != 1.0f || yScale != 1.0f) {
-        info.windowXScale *= 1.0f / xScale;
-        info.windowYScale *= 1.0f / yScale;
-        info.touchableRegion.scaleSelf(xScale, yScale);
+        // Transform layer size to screen space and inset it by surface insets.
+        layerBounds = getCroppedBufferSize(getDrawingState());
     }
 
-    // Transform layer size to screen space and inset it by surface insets.
-    Rect layerBounds = getCroppedBufferSize(getDrawingState());
     layerBounds = t.transform(layerBounds);
     layerBounds.inset(info.surfaceInset, info.surfaceInset, info.surfaceInset, info.surfaceInset);
 
@@ -2162,7 +2271,8 @@
 }
 
 bool Layer::hasInput() const {
-    return mDrawingState.inputInfo.token != nullptr;
+    Mutex::Autolock lock(mStateMutex);
+    return mState.drawing.inputInfo.token != nullptr;
 }
 
 // ---------------------------------------------------------------------------