Merge "Update BaseBundle to not use LazyValues when using ReadWriteHelper" into tm-dev

This commit is contained in:
Hani Kazmi
2022-09-01 16:51:07 +00:00
committed by Android (Google) Code Review
2 changed files with 67 additions and 2 deletions

View File

@@ -438,8 +438,11 @@ public class BaseBundle {
map.ensureCapacity(count); map.ensureCapacity(count);
} }
try { try {
// recycleParcel being false implies that we do not own the parcel. In this case, do
// not use lazy values to be safe, as the parcel could be recycled outside of our
// control.
recycleParcel &= parcelledData.readArrayMap(map, count, !parcelledByNative, recycleParcel &= parcelledData.readArrayMap(map, count, !parcelledByNative,
/* lazy */ true, mClassLoader); /* lazy */ recycleParcel, mClassLoader);
} catch (BadParcelableException e) { } catch (BadParcelableException e) {
if (sShouldDefuse) { if (sShouldDefuse) {
Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e); Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e);
@@ -1845,7 +1848,6 @@ public class BaseBundle {
// bundle immediately; neither of which is obvious. // bundle immediately; neither of which is obvious.
synchronized (this) { synchronized (this) {
initializeFromParcelLocked(parcel, /*recycleParcel=*/ false, isNativeBundle); initializeFromParcelLocked(parcel, /*recycleParcel=*/ false, isNativeBundle);
unparcel(/* itemwise */ true);
} }
return; return;
} }

View File

@@ -408,6 +408,69 @@ public class BundleTest {
assertThat(bundle.<Parcelable>getParcelable("key")).isEqualTo(parcelable); assertThat(bundle.<Parcelable>getParcelable("key")).isEqualTo(parcelable);
} }
@Test
public void readFromParcel_withLazyValues_copiesUnderlyingParcel() {
Bundle bundle = new Bundle();
Parcelable parcelable = new CustomParcelable(13, "Tiramisu");
bundle.putParcelable("key", parcelable);
bundle.putString("string", "value");
Parcel parcelledBundle = getParcelledBundle(bundle);
Bundle testBundle = new Bundle();
testBundle.setClassLoader(getClass().getClassLoader());
testBundle.readFromParcel(parcelledBundle);
// Recycle the parcel as it should have been copied
parcelledBundle.recycle();
assertThat(testBundle.getString("string")).isEqualTo("value");
assertThat(testBundle.<Parcelable>getParcelable("key")).isEqualTo(parcelable);
}
@Test
public void readFromParcelWithRwHelper_whenThrowingAndNotDefusing_throws() {
Bundle bundle = new Bundle();
Parcelable parcelable = new CustomParcelable(13, "Tiramisu");
bundle.putParcelable("key", parcelable);
bundle.putString("string", "value");
Parcel parcelledBundle = getParcelledBundle(bundle);
parcelledBundle.setReadWriteHelper(new Parcel.ReadWriteHelper());
Bundle testBundle = new Bundle();
assertThrows(BadParcelableException.class,
() -> testBundle.readFromParcel(parcelledBundle));
}
@Test
public void readFromParcelWithRwHelper_whenThrowingAndDefusing_returnsNull() {
Bundle bundle = new Bundle();
Parcelable parcelable = new CustomParcelable(13, "Tiramisu");
bundle.putParcelable("key", parcelable);
bundle.putString("string", "value");
Parcel parcelledBundle = getParcelledBundle(bundle);
parcelledBundle.setReadWriteHelper(new Parcel.ReadWriteHelper());
Bundle.setShouldDefuse(true);
Bundle testBundle = new Bundle();
testBundle.readFromParcel(parcelledBundle);
// Recycle the parcel as it should not be referenced
parcelledBundle.recycle();
assertThat(testBundle.getString("string")).isNull();
assertThat(testBundle.<Parcelable>getParcelable("key")).isNull();
}
@Test
public void readFromParcelWithRwHelper_withoutLazyObject_returnsValue() {
Bundle bundle = new Bundle();
bundle.putString("string", "value");
Parcel parcelledBundle = getParcelledBundle(bundle);
parcelledBundle.setReadWriteHelper(new Parcel.ReadWriteHelper());
Bundle testBundle = new Bundle();
testBundle.readFromParcel(parcelledBundle);
// Recycle the parcel as it should not be referenced
parcelledBundle.recycle();
assertThat(testBundle.getString("string")).isEqualTo("value");
}
@Test @Test
public void partialDeserialization_whenNotDefusing_throws() throws Exception { public void partialDeserialization_whenNotDefusing_throws() throws Exception {
Bundle.setShouldDefuse(false); Bundle.setShouldDefuse(false);