Loading core/java/android/os/BaseBundle.java +8 −10 Original line number Diff line number Diff line Loading @@ -457,11 +457,11 @@ public class BaseBundle implements Parcel.ClassLoaderProvider { if (mOwnsLazyValues) { Preconditions.checkState(mLazyValues >= 0, "Lazy values ref count below 0"); // No more lazy values in mMap, so we can recycle the parcel early rather than // No more lazy values in mMap, so we can destroy the parcel early rather than // waiting for the next GC run Parcel parcel = mWeakParcelledData.get(); if (mLazyValues == 0 && parcel != null) { recycleParcel(parcel); parcel.destroy(); mWeakParcelledData = null; } } Loading Loading @@ -516,7 +516,8 @@ public class BaseBundle implements Parcel.ClassLoaderProvider { mWeakParcelledData = null; if (ownsParcel) { if (numLazyValues[0] == 0) { recycleParcel(parcelledData); // No lazy value, we can directly recycle this parcel parcelledData.recycle(); } else { mWeakParcelledData = new WeakReference<>(parcelledData); } Loading Loading @@ -556,12 +557,6 @@ public class BaseBundle implements Parcel.ClassLoaderProvider { return p == NoImagePreloadHolder.EMPTY_PARCEL; } private static void recycleParcel(Parcel p) { if (p != null && !isEmptyParcel(p)) { p.recycle(); } } /** * Returns the backing map of this bundle after deserializing every item. * Loading Loading @@ -667,7 +662,10 @@ public class BaseBundle implements Parcel.ClassLoaderProvider { public void clear() { unparcel(); if (mOwnsLazyValues && mWeakParcelledData != null) { recycleParcel(mWeakParcelledData.get()); Parcel parcel = mWeakParcelledData.get(); if (parcel != null) { parcel.destroy(); } } mWeakParcelledData = null; Loading core/java/android/os/Parcel.java +3 −2 Original line number Diff line number Diff line Loading @@ -619,7 +619,6 @@ public final class Parcel { // able to print a stack when a Parcel is recycled twice, that // is cleared in obtain instead. mClassCookies = null; freeBuffer(); if (mOwnsNativeParcelObject) { Loading Loading @@ -5612,9 +5611,11 @@ public final class Parcel { nativeFreeBuffer(mNativePtr); } mReadWriteHelper = ReadWriteHelper.DEFAULT; mClassCookies = null; } private void destroy() { /** @hide */ public void destroy() { resetSqaushingState(); if (mNativePtr != 0) { if (mOwnsNativeParcelObject) { Loading core/tests/mockingcoretests/src/android/os/BundleRecyclingTest.java +34 −34 Original line number Diff line number Diff line Loading @@ -71,39 +71,39 @@ public class BundleRecyclingTest { } @Test public void bundleClear_whenParcelled_recyclesParcel() { public void bundleClear_whenParcelled_destroysParcel() { setUpBundle(/* lazy */ 1); assertTrue(mBundle.isParcelled()); verify(mParcelSpy, times(0)).recycle(); verify(mParcelSpy, times(0)).destroy(); mBundle.clear(); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); assertTrue(mBundle.isDefinitelyEmpty()); // Should not recycle again // Should not destroy again mBundle.clear(); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); } @Test public void bundleClear_whenUnparcelledWithLazy_recyclesParcel() { public void bundleClear_whenUnparcelledWithLazy_destroysParcel() { setUpBundle(/* lazy */ 1); // Will unparcel but keep the CustomParcelable lazy assertFalse(mBundle.isEmpty()); verify(mParcelSpy, times(0)).recycle(); verify(mParcelSpy, times(0)).destroy(); mBundle.clear(); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); assertTrue(mBundle.isDefinitelyEmpty()); // Should not recycle again mBundle.clear(); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); } @Test public void bundleClear_whenClearedWithSharedParcel_doesNotRecycleParcel() { public void bundleClear_whenClearedWithSharedParcel_doesNotDestroyParcel() { setUpBundle(/* lazy */ 1); Bundle copy = new Bundle(); Loading @@ -115,11 +115,11 @@ public class BundleRecyclingTest { copy.clear(); assertTrue(copy.isDefinitelyEmpty()); verify(mParcelSpy, never()).recycle(); verify(mParcelSpy, never()).destroy(); } @Test public void bundleClear_whenClearedWithCopiedParcel_doesNotRecycleParcel() { public void bundleClear_whenClearedWithCopiedParcel_doesNotDestroyParcel() { setUpBundle(/* lazy */ 1); // Will unparcel but keep the CustomParcelable lazy Loading @@ -134,75 +134,75 @@ public class BundleRecyclingTest { copy.clear(); assertTrue(copy.isDefinitelyEmpty()); verify(mParcelSpy, never()).recycle(); verify(mParcelSpy, never()).destroy(); } @Test public void bundleGet_whenUnparcelledWithLazyValueUnwrapped_recyclesParcel() { public void bundleGet_whenUnparcelledWithLazyValueUnwrapped_destroysParcel() { setUpBundle(/* lazy */ 1); // Will unparcel with a lazy value, and immediately unwrap the lazy value, // with no lazy values left at the end of getParcelable // Ref counting should immediately recycle assertNotNull(mBundle.getParcelable("lazy0", CustomParcelable.class)); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); // Should not recycle again assertNotNull(mBundle.getParcelable("lazy0", CustomParcelable.class)); mBundle.clear(); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); } @Test public void bundleGet_whenMultipleLazy_recyclesParcelWhenAllUnwrapped() { public void bundleGet_whenMultipleLazy_destroysParcelWhenAllUnwrapped() { setUpBundle(/* lazy */ 2); assertNotNull(mBundle.getParcelable("lazy0", CustomParcelable.class)); verify(mParcelSpy, times(0)).recycle(); verify(mParcelSpy, times(0)).destroy(); assertNotNull(mBundle.getParcelable("lazy0", CustomParcelable.class)); verify(mParcelSpy, times(0)).recycle(); verify(mParcelSpy, times(0)).destroy(); assertNotNull(mBundle.getParcelable("lazy1", CustomParcelable.class)); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); // Should not recycle again assertNotNull(mBundle.getParcelable("lazy0", CustomParcelable.class)); mBundle.clear(); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); assertTrue(mBundle.isDefinitelyEmpty()); } @Test public void bundleGet_whenLazyAndNonLazy_recyclesParcelWhenAllUnwrapped() { public void bundleGet_whenLazyAndNonLazy_destroysParcelWhenAllUnwrapped() { setUpBundle(/* lazy */ 1, /* nonLazy */ 1); assertNotNull(mBundle.getParcelable("lazy0", CustomParcelable.class)); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); // Should not recycle again // Should not destroy again assertNotNull(mBundle.getString("nonLazy0")); assertNotNull(mBundle.getParcelable("lazy0", CustomParcelable.class)); mBundle.clear(); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); } @Test public void bundleGet_whenLazyAndNonLazy_doesNotRecycleWhenOnlyNonLazyRetrieved() { public void bundleGet_whenLazyAndNonLazy_doesNotDestroyWhenOnlyNonLazyRetrieved() { setUpBundle(/* lazy */ 1, /* nonLazy */ 1); assertNotNull(mBundle.getString("nonLazy0")); verify(mParcelSpy, times(0)).recycle(); verify(mParcelSpy, times(0)).destroy(); assertNotNull(mBundle.getString("nonLazy0")); verify(mParcelSpy, times(0)).recycle(); verify(mParcelSpy, times(0)).destroy(); assertNotNull(mBundle.getParcelable("lazy0", CustomParcelable.class)); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); } @Test public void bundleGet_withWithSharedParcel_doesNotRecycleParcel() { public void bundleGet_withWithSharedParcel_doesNotDestroyParcel() { setUpBundle(/* lazy */ 1); Bundle copy = new Bundle(); Loading @@ -214,17 +214,17 @@ public class BundleRecyclingTest { assertNotNull(copy.getParcelable("lazy0", CustomParcelable.class)); copy.clear(); verify(mParcelSpy, never()).recycle(); verify(mParcelSpy, never()).destroy(); } @Test public void bundleGet_getAfterLazyCleared_doesNotRecycleAgain() { public void bundleGet_getAfterLazyCleared_doesNotDestroyAgain() { setUpBundle(/* lazy */ 1); mBundle.clear(); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); assertNull(mBundle.getParcelable("lazy0", CustomParcelable.class)); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); } private void setUpBundle(int lazy) { Loading Loading
core/java/android/os/BaseBundle.java +8 −10 Original line number Diff line number Diff line Loading @@ -457,11 +457,11 @@ public class BaseBundle implements Parcel.ClassLoaderProvider { if (mOwnsLazyValues) { Preconditions.checkState(mLazyValues >= 0, "Lazy values ref count below 0"); // No more lazy values in mMap, so we can recycle the parcel early rather than // No more lazy values in mMap, so we can destroy the parcel early rather than // waiting for the next GC run Parcel parcel = mWeakParcelledData.get(); if (mLazyValues == 0 && parcel != null) { recycleParcel(parcel); parcel.destroy(); mWeakParcelledData = null; } } Loading Loading @@ -516,7 +516,8 @@ public class BaseBundle implements Parcel.ClassLoaderProvider { mWeakParcelledData = null; if (ownsParcel) { if (numLazyValues[0] == 0) { recycleParcel(parcelledData); // No lazy value, we can directly recycle this parcel parcelledData.recycle(); } else { mWeakParcelledData = new WeakReference<>(parcelledData); } Loading Loading @@ -556,12 +557,6 @@ public class BaseBundle implements Parcel.ClassLoaderProvider { return p == NoImagePreloadHolder.EMPTY_PARCEL; } private static void recycleParcel(Parcel p) { if (p != null && !isEmptyParcel(p)) { p.recycle(); } } /** * Returns the backing map of this bundle after deserializing every item. * Loading Loading @@ -667,7 +662,10 @@ public class BaseBundle implements Parcel.ClassLoaderProvider { public void clear() { unparcel(); if (mOwnsLazyValues && mWeakParcelledData != null) { recycleParcel(mWeakParcelledData.get()); Parcel parcel = mWeakParcelledData.get(); if (parcel != null) { parcel.destroy(); } } mWeakParcelledData = null; Loading
core/java/android/os/Parcel.java +3 −2 Original line number Diff line number Diff line Loading @@ -619,7 +619,6 @@ public final class Parcel { // able to print a stack when a Parcel is recycled twice, that // is cleared in obtain instead. mClassCookies = null; freeBuffer(); if (mOwnsNativeParcelObject) { Loading Loading @@ -5612,9 +5611,11 @@ public final class Parcel { nativeFreeBuffer(mNativePtr); } mReadWriteHelper = ReadWriteHelper.DEFAULT; mClassCookies = null; } private void destroy() { /** @hide */ public void destroy() { resetSqaushingState(); if (mNativePtr != 0) { if (mOwnsNativeParcelObject) { Loading
core/tests/mockingcoretests/src/android/os/BundleRecyclingTest.java +34 −34 Original line number Diff line number Diff line Loading @@ -71,39 +71,39 @@ public class BundleRecyclingTest { } @Test public void bundleClear_whenParcelled_recyclesParcel() { public void bundleClear_whenParcelled_destroysParcel() { setUpBundle(/* lazy */ 1); assertTrue(mBundle.isParcelled()); verify(mParcelSpy, times(0)).recycle(); verify(mParcelSpy, times(0)).destroy(); mBundle.clear(); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); assertTrue(mBundle.isDefinitelyEmpty()); // Should not recycle again // Should not destroy again mBundle.clear(); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); } @Test public void bundleClear_whenUnparcelledWithLazy_recyclesParcel() { public void bundleClear_whenUnparcelledWithLazy_destroysParcel() { setUpBundle(/* lazy */ 1); // Will unparcel but keep the CustomParcelable lazy assertFalse(mBundle.isEmpty()); verify(mParcelSpy, times(0)).recycle(); verify(mParcelSpy, times(0)).destroy(); mBundle.clear(); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); assertTrue(mBundle.isDefinitelyEmpty()); // Should not recycle again mBundle.clear(); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); } @Test public void bundleClear_whenClearedWithSharedParcel_doesNotRecycleParcel() { public void bundleClear_whenClearedWithSharedParcel_doesNotDestroyParcel() { setUpBundle(/* lazy */ 1); Bundle copy = new Bundle(); Loading @@ -115,11 +115,11 @@ public class BundleRecyclingTest { copy.clear(); assertTrue(copy.isDefinitelyEmpty()); verify(mParcelSpy, never()).recycle(); verify(mParcelSpy, never()).destroy(); } @Test public void bundleClear_whenClearedWithCopiedParcel_doesNotRecycleParcel() { public void bundleClear_whenClearedWithCopiedParcel_doesNotDestroyParcel() { setUpBundle(/* lazy */ 1); // Will unparcel but keep the CustomParcelable lazy Loading @@ -134,75 +134,75 @@ public class BundleRecyclingTest { copy.clear(); assertTrue(copy.isDefinitelyEmpty()); verify(mParcelSpy, never()).recycle(); verify(mParcelSpy, never()).destroy(); } @Test public void bundleGet_whenUnparcelledWithLazyValueUnwrapped_recyclesParcel() { public void bundleGet_whenUnparcelledWithLazyValueUnwrapped_destroysParcel() { setUpBundle(/* lazy */ 1); // Will unparcel with a lazy value, and immediately unwrap the lazy value, // with no lazy values left at the end of getParcelable // Ref counting should immediately recycle assertNotNull(mBundle.getParcelable("lazy0", CustomParcelable.class)); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); // Should not recycle again assertNotNull(mBundle.getParcelable("lazy0", CustomParcelable.class)); mBundle.clear(); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); } @Test public void bundleGet_whenMultipleLazy_recyclesParcelWhenAllUnwrapped() { public void bundleGet_whenMultipleLazy_destroysParcelWhenAllUnwrapped() { setUpBundle(/* lazy */ 2); assertNotNull(mBundle.getParcelable("lazy0", CustomParcelable.class)); verify(mParcelSpy, times(0)).recycle(); verify(mParcelSpy, times(0)).destroy(); assertNotNull(mBundle.getParcelable("lazy0", CustomParcelable.class)); verify(mParcelSpy, times(0)).recycle(); verify(mParcelSpy, times(0)).destroy(); assertNotNull(mBundle.getParcelable("lazy1", CustomParcelable.class)); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); // Should not recycle again assertNotNull(mBundle.getParcelable("lazy0", CustomParcelable.class)); mBundle.clear(); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); assertTrue(mBundle.isDefinitelyEmpty()); } @Test public void bundleGet_whenLazyAndNonLazy_recyclesParcelWhenAllUnwrapped() { public void bundleGet_whenLazyAndNonLazy_destroysParcelWhenAllUnwrapped() { setUpBundle(/* lazy */ 1, /* nonLazy */ 1); assertNotNull(mBundle.getParcelable("lazy0", CustomParcelable.class)); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); // Should not recycle again // Should not destroy again assertNotNull(mBundle.getString("nonLazy0")); assertNotNull(mBundle.getParcelable("lazy0", CustomParcelable.class)); mBundle.clear(); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); } @Test public void bundleGet_whenLazyAndNonLazy_doesNotRecycleWhenOnlyNonLazyRetrieved() { public void bundleGet_whenLazyAndNonLazy_doesNotDestroyWhenOnlyNonLazyRetrieved() { setUpBundle(/* lazy */ 1, /* nonLazy */ 1); assertNotNull(mBundle.getString("nonLazy0")); verify(mParcelSpy, times(0)).recycle(); verify(mParcelSpy, times(0)).destroy(); assertNotNull(mBundle.getString("nonLazy0")); verify(mParcelSpy, times(0)).recycle(); verify(mParcelSpy, times(0)).destroy(); assertNotNull(mBundle.getParcelable("lazy0", CustomParcelable.class)); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); } @Test public void bundleGet_withWithSharedParcel_doesNotRecycleParcel() { public void bundleGet_withWithSharedParcel_doesNotDestroyParcel() { setUpBundle(/* lazy */ 1); Bundle copy = new Bundle(); Loading @@ -214,17 +214,17 @@ public class BundleRecyclingTest { assertNotNull(copy.getParcelable("lazy0", CustomParcelable.class)); copy.clear(); verify(mParcelSpy, never()).recycle(); verify(mParcelSpy, never()).destroy(); } @Test public void bundleGet_getAfterLazyCleared_doesNotRecycleAgain() { public void bundleGet_getAfterLazyCleared_doesNotDestroyAgain() { setUpBundle(/* lazy */ 1); mBundle.clear(); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); assertNull(mBundle.getParcelable("lazy0", CustomParcelable.class)); verify(mParcelSpy, times(1)).recycle(); verify(mParcelSpy, times(1)).destroy(); } private void setUpBundle(int lazy) { Loading