diff options
| -rw-r--r-- | core/java/android/app/timedetector/TimeSignal.java | 5 | ||||
| -rw-r--r-- | core/java/android/util/TimestampedValue.java | 89 | ||||
| -rw-r--r-- | core/tests/coretests/src/android/util/TimestampedValueTest.java | 29 |
3 files changed, 54 insertions, 69 deletions
diff --git a/core/java/android/app/timedetector/TimeSignal.java b/core/java/android/app/timedetector/TimeSignal.java index da21794cd649..b49426000d88 100644 --- a/core/java/android/app/timedetector/TimeSignal.java +++ b/core/java/android/app/timedetector/TimeSignal.java @@ -56,8 +56,7 @@ public final class TimeSignal implements Parcelable { private static TimeSignal createFromParcel(Parcel in) { String sourceId = in.readString(); - TimestampedValue<Long> utcTime = - TimestampedValue.readFromParcel(in, null /* classLoader */, Long.class); + TimestampedValue<Long> utcTime = in.readParcelable(null /* classLoader */); return new TimeSignal(sourceId, utcTime); } @@ -69,7 +68,7 @@ public final class TimeSignal implements Parcelable { @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeString(mSourceId); - TimestampedValue.writeToParcel(dest, mUtcTime); + dest.writeParcelable(mUtcTime, 0); } @NonNull diff --git a/core/java/android/util/TimestampedValue.java b/core/java/android/util/TimestampedValue.java index 1289e4db0743..45056730b08b 100644 --- a/core/java/android/util/TimestampedValue.java +++ b/core/java/android/util/TimestampedValue.java @@ -19,6 +19,7 @@ package android.util; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; +import android.os.Parcelable; import android.os.SystemClock; import java.util.Objects; @@ -30,14 +31,14 @@ import java.util.Objects; * If a suitable clock is used the reference time can be used to identify the age of a value or * ordering between values. * - * <p>To read and write a timestamped value from / to a Parcel see - * {@link #readFromParcel(Parcel, ClassLoader, Class)} and - * {@link #writeToParcel(Parcel, TimestampedValue)}. + * <p>This class implements {@link Parcelable} for convenience but instances will only actually be + * parcelable if the value type held is {@code null}, {@link Parcelable}, or one of the other types + * supported by {@link Parcel#writeValue(Object)} / {@link Parcel#readValue(ClassLoader)}. * * @param <T> the type of the value with an associated timestamp * @hide */ -public final class TimestampedValue<T> { +public final class TimestampedValue<T> implements Parcelable { private final long mReferenceTimeMillis; private final T mValue; @@ -81,57 +82,43 @@ public final class TimestampedValue<T> { } /** - * Read a {@link TimestampedValue} from a parcel that was stored using - * {@link #writeToParcel(Parcel, TimestampedValue)}. - * - * <p>The marshalling/unmarshalling of the value relies upon {@link Parcel#writeValue(Object)} - * and {@link Parcel#readValue(ClassLoader)} and so this method can only be used with types - * supported by those methods. - * - * @param in the Parcel to read from - * @param classLoader the ClassLoader to pass to {@link Parcel#readValue(ClassLoader)} - * @param valueClass the expected type of the value, typically the same as {@code <T>} but can - * also be a subclass - * @throws RuntimeException if the value read is not compatible with {@code valueClass} or the - * object could not be read - */ - @SuppressWarnings("unchecked") - @NonNull - public static <T> TimestampedValue<T> readFromParcel( - @NonNull Parcel in, @Nullable ClassLoader classLoader, Class<? extends T> valueClass) { - long referenceTimeMillis = in.readLong(); - T value = (T) in.readValue(classLoader); - // Equivalent to static code: if (!(value.getClass() instanceof {valueClass})) { - if (value != null && !valueClass.isAssignableFrom(value.getClass())) { - throw new RuntimeException("Value was of type " + value.getClass() - + " is not assignable to " + valueClass); - } - return new TimestampedValue<>(referenceTimeMillis, value); - } - - /** - * Write a {@link TimestampedValue} to a parcel so that it can be read using - * {@link #readFromParcel(Parcel, ClassLoader, Class)}. - * - * <p>The marshalling/unmarshalling of the value relies upon {@link Parcel#writeValue(Object)} - * and {@link Parcel#readValue(ClassLoader)} and so this method can only be used with types - * supported by those methods. - * - * @param dest the Parcel - * @param timestampedValue the value - * @throws RuntimeException if the value could not be written to the Parcel - */ - public static void writeToParcel( - @NonNull Parcel dest, @NonNull TimestampedValue<?> timestampedValue) { - dest.writeLong(timestampedValue.mReferenceTimeMillis); - dest.writeValue(timestampedValue.mValue); - } - - /** * Returns the difference in milliseconds between two instance's reference times. */ public static long referenceTimeDifference( @NonNull TimestampedValue<?> one, @NonNull TimestampedValue<?> two) { return one.mReferenceTimeMillis - two.mReferenceTimeMillis; } + + public static final @NonNull Parcelable.Creator<TimestampedValue<?>> CREATOR = + new Parcelable.ClassLoaderCreator<TimestampedValue<?>>() { + + @Override + public TimestampedValue<?> createFromParcel(@NonNull Parcel source) { + return createFromParcel(source, null); + } + + @Override + public TimestampedValue<?> createFromParcel( + @NonNull Parcel source, @Nullable ClassLoader classLoader) { + long referenceTimeMillis = source.readLong(); + Object value = source.readValue(classLoader); + return new TimestampedValue<>(referenceTimeMillis, value); + } + + @Override + public TimestampedValue[] newArray(int size) { + return new TimestampedValue[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeLong(mReferenceTimeMillis); + dest.writeValue(mValue); + } } diff --git a/core/tests/coretests/src/android/util/TimestampedValueTest.java b/core/tests/coretests/src/android/util/TimestampedValueTest.java index 6e3ab796c5d3..6fc2400316c2 100644 --- a/core/tests/coretests/src/android/util/TimestampedValueTest.java +++ b/core/tests/coretests/src/android/util/TimestampedValueTest.java @@ -55,12 +55,12 @@ public class TimestampedValueTest { TimestampedValue<String> stringValue = new TimestampedValue<>(1000, "Hello"); Parcel parcel = Parcel.obtain(); try { - TimestampedValue.writeToParcel(parcel, stringValue); + parcel.writeParcelable(stringValue, 0); parcel.setDataPosition(0); TimestampedValue<String> stringValueCopy = - TimestampedValue.readFromParcel(parcel, null /* classLoader */, String.class); + parcel.readParcelable(null /* classLoader */); assertEquals(stringValue, stringValueCopy); } finally { parcel.recycle(); @@ -72,12 +72,12 @@ public class TimestampedValueTest { TimestampedValue<String> stringValue = new TimestampedValue<>(1000, "Hello"); Parcel parcel = Parcel.obtain(); try { - TimestampedValue.writeToParcel(parcel, stringValue); + parcel.writeParcelable(stringValue, 0); parcel.setDataPosition(0); - TimestampedValue<Object> stringValueCopy = - TimestampedValue.readFromParcel(parcel, null /* classLoader */, Object.class); + TimestampedValue<String> stringValueCopy = + parcel.readParcelable(null /* classLoader */); assertEquals(stringValue, stringValueCopy); } finally { parcel.recycle(); @@ -85,15 +85,15 @@ public class TimestampedValueTest { } @Test - public void testParceling_valueClassIncompatible() { - TimestampedValue<String> stringValue = new TimestampedValue<>(1000, "Hello"); + public void testParceling_valueClassNotParcelable() { + // This class is not one supported by Parcel.writeValue(). + class NotParcelable {} + + TimestampedValue<NotParcelable> notParcelableValue = + new TimestampedValue<>(1000, new NotParcelable()); Parcel parcel = Parcel.obtain(); try { - TimestampedValue.writeToParcel(parcel, stringValue); - - parcel.setDataPosition(0); - - TimestampedValue.readFromParcel(parcel, null /* classLoader */, Double.class); + parcel.writeParcelable(notParcelableValue, 0); fail(); } catch (RuntimeException expected) { } finally { @@ -106,12 +106,11 @@ public class TimestampedValueTest { TimestampedValue<String> nullValue = new TimestampedValue<>(1000, null); Parcel parcel = Parcel.obtain(); try { - TimestampedValue.writeToParcel(parcel, nullValue); + parcel.writeParcelable(nullValue, 0); parcel.setDataPosition(0); - TimestampedValue<Object> nullValueCopy = - TimestampedValue.readFromParcel(parcel, null /* classLoader */, String.class); + TimestampedValue<String> nullValueCopy = parcel.readParcelable(null /* classLoader */); assertEquals(nullValue, nullValueCopy); } finally { parcel.recycle(); |