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

Commit 8a86825e authored by Amith Yamasani's avatar Amith Yamasani Committed by Android (Google) Code Review
Browse files

Merge "Fix for race in writeToParcel and unparcel"

parents a532c3ff 69475346
Loading
Loading
Loading
Loading
+58 −52
Original line number Diff line number Diff line
@@ -213,7 +213,7 @@ public class BaseBundle {
     * If the underlying data are stored as a Parcel, unparcel them
     * using the currently assigned class loader.
     */
    /* package */ synchronized void unparcel() {
    /* package */ void unparcel() {
        synchronized (this) {
            final Parcel parcelledData = mParcelledData;
            if (parcelledData == null) {
@@ -319,12 +319,14 @@ public class BaseBundle {
    }

    void copyInternal(BaseBundle from, boolean deep) {
        synchronized (from) {
            if (from.mParcelledData != null) {
                if (from.isEmptyParcel()) {
                    mParcelledData = NoImagePreloadHolder.EMPTY_PARCEL;
                } else {
                    mParcelledData = Parcel.obtain();
                mParcelledData.appendFrom(from.mParcelledData, 0, from.mParcelledData.dataSize());
                    mParcelledData.appendFrom(from.mParcelledData, 0,
                            from.mParcelledData.dataSize());
                    mParcelledData.setDataPosition(0);
                }
            } else {
@@ -348,6 +350,7 @@ public class BaseBundle {

            mClassLoader = from.mClassLoader;
        }
    }

    Object deepcopyValue(Object value) {
        if (value == null) {
@@ -1441,22 +1444,26 @@ public class BaseBundle {
    void writeToParcelInner(Parcel parcel, int flags) {
        // Keep implementation in sync with writeToParcel() in
        // frameworks/native/libs/binder/PersistableBundle.cpp.
        final Parcel parcelledData;
        final ArrayMap<String, Object> map;
        synchronized (this) {
            parcelledData = mParcelledData;
        }
        if (parcelledData != null) {
            if (isEmptyParcel()) {
            // unparcel() can race with this method and cause the parcel to recycle
            // at the wrong time. So synchronize access the mParcelledData's content.
            if (mParcelledData != null) {
                if (mParcelledData == NoImagePreloadHolder.EMPTY_PARCEL) {
                    parcel.writeInt(0);
                } else {
                int length = parcelledData.dataSize();
                    int length = mParcelledData.dataSize();
                    parcel.writeInt(length);
                    parcel.writeInt(BUNDLE_MAGIC);
                parcel.appendFrom(parcelledData, 0, length);
                    parcel.appendFrom(mParcelledData, 0, length);
                }
        } else {
                return;
            }
            map = mMap;
        }

        // Special case for empty bundles.
            if (mMap == null || mMap.size() <= 0) {
        if (map == null || map.size() <= 0) {
            parcel.writeInt(0);
            return;
        }
@@ -1465,7 +1472,7 @@ public class BaseBundle {
        parcel.writeInt(BUNDLE_MAGIC);

        int startPos = parcel.dataPosition();
            parcel.writeArrayMapInternal(mMap);
        parcel.writeArrayMapInternal(map);
        int endPos = parcel.dataPosition();

        // Backpatch length
@@ -1474,7 +1481,6 @@ public class BaseBundle {
        parcel.writeInt(length);
        parcel.setDataPosition(endPos);
    }
    }

    /**
     * Reads the Parcel contents into this Bundle, typically in order for