File: TimestampedValue.java

package info (click to toggle)
android-platform-frameworks-base 1%3A10.0.0%2Br36-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 321,788 kB
  • sloc: java: 962,234; cpp: 274,314; xml: 242,770; python: 5,060; sh: 1,432; ansic: 494; makefile: 47; sed: 19
file content (137 lines) | stat: -rw-r--r-- 5,173 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
 * 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);
    }

    @Override
    public String toString() {
        return "TimestampedValue{"
                + "mReferenceTimeMillis=" + mReferenceTimeMillis
                + ", mValue=" + 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);
    }

    /**
     * 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;
    }
}