Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 05f920bb authored by Vishnu Nair's avatar Vishnu Nair Committed by Android (Google) Code Review
Browse files

Merge "SurfaceView: Fix unsafe transaction accesses"

parents d79387b5 894fa880
Loading
Loading
Loading
Loading
+49 −56
Original line number Diff line number Diff line
@@ -138,20 +138,9 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
    private boolean mDisableBackgroundLayer = false;

    /**
     * We use this lock in SOME cases when reading or writing SurfaceControl,
     * but use the following model so that the RenderThread can run locklessly
     * in the position up-date case.
     *
     * 1. UI Thread can read from mSurfaceControl (use in Transactions) without
     * holding the lock.
     * 2. UI Thread will hold the lock when writing to mSurfaceControl (calling release
     * or remove).
     * 3. Render thread will also hold the lock when writing to mSurfaceControl (e.g.
     * calling release from positionLost).
     * 3. RenderNode.PositionUpdateListener::positionChanged will only be called
     * when the UI thread is paused (blocked on the Render thread).
     * 4. positionChanged thus will not be required to hold the lock as the
     * UI thread is blocked, and the other writer is the RT itself.
     * We use this lock to protect access to mSurfaceControl and 
     * SurfaceViewPositionUpdateListener#mPositionChangedTransaction. Both are accessed on the UI
     * thread and the render thread.
     */
    final Object mSurfaceControlLock = new Object();
    final Rect mTmpRect = new Rect();
@@ -951,8 +940,10 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
            Transaction geometryTransaction) {
        if (mPositionListener != null) {
            mRenderNode.removePositionUpdateListener(mPositionListener);
            synchronized (mSurfaceControlLock) {
                geometryTransaction = mPositionListener.getTransaction().merge(geometryTransaction);
            }
        }
        mPositionListener = new SurfaceViewPositionUpdateListener(surfaceWidth, surfaceHeight,
                geometryTransaction);
        mRenderNode.addPositionUpdateListener(mPositionListener);
@@ -1480,7 +1471,6 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
                if (mSurfaceControl == null) {
                    return;
                }
            }
                if (mRTLastReportedPosition.left == left
                        && mRTLastReportedPosition.top == top
                        && mRTLastReportedPosition.right == right
@@ -1503,8 +1493,10 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
                    onSetSurfacePositionAndScaleRT(mPositionChangedTransaction, mSurfaceControl,
                            mRTLastReportedPosition.left /*positionLeft*/,
                            mRTLastReportedPosition.top /*positionTop*/,
                        mRTLastReportedPosition.width() / (float) mRtSurfaceWidth /*postScaleX*/,
                        mRTLastReportedPosition.height() / (float) mRtSurfaceHeight /*postScaleY*/);
                            mRTLastReportedPosition.width()
                                    / (float) mRtSurfaceWidth /*postScaleX*/,
                            mRTLastReportedPosition.height()
                                    / (float) mRtSurfaceHeight /*postScaleY*/);
                    if (mViewVisibility) {
                        mPositionChangedTransaction.show(mSurfaceControl);
                    }
@@ -1519,6 +1511,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
                    Log.e(TAG, "Exception from repositionChild", ex);
                }
            }
        }

        @Override
        public void applyStretch(long frameNumber, float width, float height,
@@ -1539,18 +1532,18 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
            }
            mRTLastReportedPosition.setEmpty();
            mRTLastReportedSurfaceSize.set(-1, -1);
            if (mPendingTransaction) {
                Log.w(TAG, System.identityHashCode(SurfaceView.this)
                        + "Pending transaction cleared.");
                mPositionChangedTransaction.clear();
                mPendingTransaction = false;
            }

            /**
             * positionLost can be called while UI thread is un-paused so we
             * need to hold the lock here.
             */
            synchronized (mSurfaceControlLock) {
                if (mPendingTransaction) {
                    Log.w(TAG, System.identityHashCode(SurfaceView.this)
                            + "Pending transaction cleared.");
                    mPositionChangedTransaction.clear();
                    mPendingTransaction = false;
                }
                if (mSurfaceControl == null) {
                    return;
                }