Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ed497ce authored by Neil Fuller's avatar Neil Fuller Committed by Android (Google) Code Review
Browse files

Merge "Simple pass-through TimeDetectorService"

parents 63099bbc 24836bfb
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.app.timedetector;

import android.app.timedetector.TimeSignal;

/**
 * System private API to comunicate with time detector service.
 *
@@ -30,5 +32,5 @@ package android.app.timedetector;
 * {@hide}
 */
interface ITimeDetectorService {
  void stubbedCall();
  void suggestTime(in TimeSignal timeSignal);
}
+7 −5
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.app.timedetector;

import android.annotation.NonNull;
import android.annotation.SystemService;
import android.content.Context;
import android.os.RemoteException;
@@ -40,15 +41,16 @@ public final class TimeDetector {
    }

    /**
     * Does nothing.
     * TODO: Remove this when the service implementation is built out.
     * Suggests the current time to the detector. The detector may ignore the signal if better
     * signals are available such as those that come from more reliable sources or were
     * determined more recently.
     */
    public void stubbedCall() {
    public void suggestTime(@NonNull TimeSignal timeSignal) {
        if (DEBUG) {
            Log.d(TAG, "stubbedCall called");
            Log.d(TAG, "suggestTime called: " + timeSignal);
        }
        try {
            mITimeDetectorService.stubbedCall();
            mITimeDetectorService.suggestTime(timeSignal);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+19 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.app.timedetector;

parcelable TimeSignal;
 No newline at end of file
+110 −0
Original line number Diff line number Diff line
/*
 * 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.app.timedetector;

import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.TimestampedValue;

import java.util.Objects;

/**
 * A time signal from a named source. The value consists of the number of milliseconds elapsed since
 * 1/1/1970 00:00:00 UTC and the time according to the elapsed realtime clock when that number was
 * established. The elapsed realtime clock is considered accurate but volatile, so time signals
 * must not be persisted across device resets.
 *
 * @hide
 */
public final class TimeSignal implements Parcelable {

    public static final Parcelable.Creator<TimeSignal> CREATOR =
            new Parcelable.Creator<TimeSignal>() {
                public TimeSignal createFromParcel(Parcel in) {
                    return TimeSignal.createFromParcel(in);
                }

                public TimeSignal[] newArray(int size) {
                    return new TimeSignal[size];
                }
            };

    public static final String SOURCE_ID_NITZ = "nitz";

    private final String mSourceId;
    private final TimestampedValue<Long> mUtcTime;

    public TimeSignal(String sourceId, TimestampedValue<Long> utcTime) {
        mSourceId = Objects.requireNonNull(sourceId);
        mUtcTime = Objects.requireNonNull(utcTime);
    }

    private static TimeSignal createFromParcel(Parcel in) {
        String sourceId = in.readString();
        TimestampedValue<Long> utcTime =
                TimestampedValue.readFromParcel(in, null /* classLoader */, Long.class);
        return new TimeSignal(sourceId, utcTime);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeString(mSourceId);
        TimestampedValue.writeToParcel(dest, mUtcTime);
    }

    @NonNull
    public String getSourceId() {
        return mSourceId;
    }

    @NonNull
    public TimestampedValue<Long> getUtcTime() {
        return mUtcTime;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        TimeSignal that = (TimeSignal) o;
        return Objects.equals(mSourceId, that.mSourceId)
                && Objects.equals(mUtcTime, that.mUtcTime);
    }

    @Override
    public int hashCode() {
        return Objects.hash(mSourceId, mUtcTime);
    }

    @Override
    public String toString() {
        return "TimeSignal{"
                + "mSourceId='" + mSourceId + '\''
                + ", mUtcTime=" + mUtcTime
                + '}';
    }
}
+121 −0
Original line number Diff line number Diff line
/*
 * 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);
    }
}
Loading