diff options
Diffstat (limited to 'core/java/android/util')
| -rw-r--r-- | core/java/android/util/TimestampedValue.java | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/core/java/android/util/TimestampedValue.java b/core/java/android/util/TimestampedValue.java new file mode 100644 index 000000000000..21603801d4cb --- /dev/null +++ b/core/java/android/util/TimestampedValue.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.util; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.Parcel; +import android.os.SystemClock; + +import java.util.Objects; + +/** + * A value with an associated reference time. The reference time will typically be provided by the + * elapsed realtime clock. The elapsed realtime clock can be obtained using methods like + * {@link SystemClock#elapsedRealtime()} or {@link SystemClock#elapsedRealtimeClock()}. + * 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)}. + * + * @param <T> the type of the value with an associated timestamp + * @hide + */ +public final class TimestampedValue<T> { + private final long mReferenceTimeMillis; + private final T mValue; + + public TimestampedValue(long referenceTimeMillis, T value) { + mReferenceTimeMillis = referenceTimeMillis; + mValue = value; + } + + public long getReferenceTimeMillis() { + return mReferenceTimeMillis; + } + + public T getValue() { + return mValue; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TimestampedValue<?> that = (TimestampedValue<?>) o; + return mReferenceTimeMillis == that.mReferenceTimeMillis + && Objects.equals(mValue, that.mValue); + } + + @Override + public int hashCode() { + return Objects.hash(mReferenceTimeMillis, mValue); + } + + /** + * 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); + } +} |
