Simple pass-through TimeDetectorService

This is sufficient to wire up time detection from telephony
to the new service without breaking time detection.

This cherry-pick contains a small change: to use
SystemClock.elapsedRealtime() instead of the newer
SystemClock.elapsedRealtimeClock() with Clock.millis().

Bug: 78217059
Test: atest FrameworksServicesTests:com.android.server.timedetector
Test: atest FrameworksCoreTests:android.util.TimestampedValueTest
Merged-In: Id7175878dc22e5272c31f3e478af4b0e4183b62b
Change-Id: Id7175878dc22e5272c31f3e478af4b0e4183b62b
(cherry picked from commit 24836bfb1564b1f98c322108a924965a8dbbee4f)
diff --git a/core/java/android/util/TimestampedValue.java b/core/java/android/util/TimestampedValue.java
new file mode 100644
index 0000000..2160380
--- /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);
+    }
+}