Merge "Add a path for GNSS time suggestions"
This commit is contained in:
19
core/java/android/app/timedetector/GnssTimeSuggestion.aidl
Normal file
19
core/java/android/app/timedetector/GnssTimeSuggestion.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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 GnssTimeSuggestion;
|
||||
135
core/java/android/app/timedetector/GnssTimeSuggestion.java
Normal file
135
core/java/android/app/timedetector/GnssTimeSuggestion.java
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.annotation.Nullable;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.TimestampedValue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A time signal from a GNSS source.
|
||||
*
|
||||
* <p>{@code utcTime} is the suggested time. The {@code utcTime.value} is the number of milliseconds
|
||||
* elapsed since 1/1/1970 00:00:00 UTC. The {@code utcTime.referenceTimeMillis} is the value of the
|
||||
* elapsed realtime clock when the {@code utcTime.value} was established.
|
||||
* Note that the elapsed realtime clock is considered accurate but it is volatile, so time
|
||||
* suggestions cannot be persisted across device resets.
|
||||
*
|
||||
* <p>{@code debugInfo} contains debugging metadata associated with the suggestion. This is used to
|
||||
* record why the suggestion exists and how it was entered. This information exists only to aid in
|
||||
* debugging and therefore is used by {@link #toString()}, but it is not for use in detection
|
||||
* logic and is not considered in {@link #hashCode()} or {@link #equals(Object)}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class GnssTimeSuggestion implements Parcelable {
|
||||
|
||||
public static final @NonNull Creator<GnssTimeSuggestion> CREATOR =
|
||||
new Creator<GnssTimeSuggestion>() {
|
||||
public GnssTimeSuggestion createFromParcel(Parcel in) {
|
||||
return GnssTimeSuggestion.createFromParcel(in);
|
||||
}
|
||||
|
||||
public GnssTimeSuggestion[] newArray(int size) {
|
||||
return new GnssTimeSuggestion[size];
|
||||
}
|
||||
};
|
||||
|
||||
@NonNull private final TimestampedValue<Long> mUtcTime;
|
||||
@Nullable private ArrayList<String> mDebugInfo;
|
||||
|
||||
public GnssTimeSuggestion(@NonNull TimestampedValue<Long> utcTime) {
|
||||
mUtcTime = Objects.requireNonNull(utcTime);
|
||||
Objects.requireNonNull(utcTime.getValue());
|
||||
}
|
||||
|
||||
private static GnssTimeSuggestion createFromParcel(Parcel in) {
|
||||
TimestampedValue<Long> utcTime = in.readParcelable(null /* classLoader */);
|
||||
GnssTimeSuggestion suggestion = new GnssTimeSuggestion(utcTime);
|
||||
@SuppressWarnings("unchecked")
|
||||
ArrayList<String> debugInfo = (ArrayList<String>) in.readArrayList(null /* classLoader */);
|
||||
suggestion.mDebugInfo = debugInfo;
|
||||
return suggestion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeParcelable(mUtcTime, 0);
|
||||
dest.writeList(mDebugInfo);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public TimestampedValue<Long> getUtcTime() {
|
||||
return mUtcTime;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public List<String> getDebugInfo() {
|
||||
return mDebugInfo == null
|
||||
? Collections.emptyList() : Collections.unmodifiableList(mDebugInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates information with the instance that can be useful for debugging / logging. The
|
||||
* information is present in {@link #toString()} but is not considered for
|
||||
* {@link #equals(Object)} and {@link #hashCode()}.
|
||||
*/
|
||||
public void addDebugInfo(String... debugInfos) {
|
||||
if (mDebugInfo == null) {
|
||||
mDebugInfo = new ArrayList<>();
|
||||
}
|
||||
mDebugInfo.addAll(Arrays.asList(debugInfos));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
GnssTimeSuggestion that = (GnssTimeSuggestion) o;
|
||||
return Objects.equals(mUtcTime, that.mUtcTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mUtcTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GnssTimeSuggestion{"
|
||||
+ "mUtcTime=" + mUtcTime
|
||||
+ ", mDebugInfo=" + mDebugInfo
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.app.timedetector;
|
||||
|
||||
import android.app.timedetector.GnssTimeSuggestion;
|
||||
import android.app.timedetector.ManualTimeSuggestion;
|
||||
import android.app.timedetector.NetworkTimeSuggestion;
|
||||
import android.app.timedetector.TelephonyTimeSuggestion;
|
||||
@@ -34,6 +35,7 @@ import android.app.timedetector.TelephonyTimeSuggestion;
|
||||
* {@hide}
|
||||
*/
|
||||
interface ITimeDetectorService {
|
||||
void suggestGnssTime(in GnssTimeSuggestion timeSuggestion);
|
||||
boolean suggestManualTime(in ManualTimeSuggestion timeSuggestion);
|
||||
void suggestNetworkTime(in NetworkTimeSuggestion timeSuggestion);
|
||||
void suggestTelephonyTime(in TelephonyTimeSuggestion timeSuggestion);
|
||||
|
||||
@@ -71,4 +71,12 @@ public interface TimeDetector {
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.SET_TIME)
|
||||
void suggestNetworkTime(NetworkTimeSuggestion timeSuggestion);
|
||||
|
||||
/**
|
||||
* Suggests the time according to a gnss time source.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.SET_TIME)
|
||||
void suggestGnssTime(GnssTimeSuggestion timeSuggestion);
|
||||
}
|
||||
|
||||
@@ -74,4 +74,16 @@ public final class TimeDetectorImpl implements TimeDetector {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suggestGnssTime(GnssTimeSuggestion timeSuggestion) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "suggestGnssTime called: " + timeSuggestion);
|
||||
}
|
||||
try {
|
||||
mITimeDetectorService.suggestGnssTime(timeSuggestion);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2020 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 static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
|
||||
import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcelable;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
||||
import android.os.TimestampedValue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class GnssTimeSuggestionTest {
|
||||
|
||||
private static final TimestampedValue<Long> ARBITRARY_TIME =
|
||||
new TimestampedValue<>(1111L, 2222L);
|
||||
|
||||
@Test
|
||||
public void testEquals() {
|
||||
GnssTimeSuggestion one = new GnssTimeSuggestion(ARBITRARY_TIME);
|
||||
assertEquals(one, one);
|
||||
|
||||
GnssTimeSuggestion two = new GnssTimeSuggestion(ARBITRARY_TIME);
|
||||
assertEquals(one, two);
|
||||
assertEquals(two, one);
|
||||
|
||||
TimestampedValue<Long> differentTime = new TimestampedValue<>(
|
||||
ARBITRARY_TIME.getReferenceTimeMillis() + 1,
|
||||
ARBITRARY_TIME.getValue());
|
||||
GnssTimeSuggestion three = new GnssTimeSuggestion(differentTime);
|
||||
assertNotEquals(one, three);
|
||||
assertNotEquals(three, one);
|
||||
|
||||
// DebugInfo must not be considered in equals().
|
||||
one.addDebugInfo("Debug info 1");
|
||||
two.addDebugInfo("Debug info 2");
|
||||
assertEquals(one, two);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParcelable() {
|
||||
GnssTimeSuggestion suggestion = new GnssTimeSuggestion(ARBITRARY_TIME);
|
||||
assertRoundTripParcelable(suggestion);
|
||||
|
||||
// DebugInfo should also be stored (but is not checked by equals()
|
||||
suggestion.addDebugInfo("This is debug info");
|
||||
GnssTimeSuggestion rtSuggestion = roundTripParcelable(suggestion);
|
||||
assertEquals(suggestion.getDebugInfo(), rtSuggestion.getDebugInfo());
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package com.android.server.timedetector;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.timedetector.GnssTimeSuggestion;
|
||||
import android.app.timedetector.ITimeDetectorService;
|
||||
import android.app.timedetector.ManualTimeSuggestion;
|
||||
import android.app.timedetector.NetworkTimeSuggestion;
|
||||
@@ -122,6 +123,14 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub {
|
||||
mHandler.post(() -> mTimeDetectorStrategy.suggestNetworkTime(timeSignal));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suggestGnssTime(@NonNull GnssTimeSuggestion timeSignal) {
|
||||
enforceSuggestGnssTimePermission();
|
||||
Objects.requireNonNull(timeSignal);
|
||||
|
||||
mHandler.post(() -> mTimeDetectorStrategy.suggestGnssTime(timeSignal));
|
||||
}
|
||||
|
||||
/** Internal method for handling the auto time setting being changed. */
|
||||
@VisibleForTesting
|
||||
public void handleAutoTimeDetectionChanged() {
|
||||
@@ -153,4 +162,10 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub {
|
||||
android.Manifest.permission.SET_TIME,
|
||||
"set time");
|
||||
}
|
||||
|
||||
private void enforceSuggestGnssTimePermission() {
|
||||
mContext.enforceCallingOrSelfPermission(
|
||||
android.Manifest.permission.SET_TIME,
|
||||
"suggest gnss time");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.server.timedetector;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.timedetector.GnssTimeSuggestion;
|
||||
import android.app.timedetector.ManualTimeSuggestion;
|
||||
import android.app.timedetector.NetworkTimeSuggestion;
|
||||
import android.app.timedetector.TelephonyTimeSuggestion;
|
||||
@@ -40,7 +41,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||
*/
|
||||
public interface TimeDetectorStrategy {
|
||||
|
||||
@IntDef({ ORIGIN_TELEPHONY, ORIGIN_MANUAL, ORIGIN_NETWORK })
|
||||
@IntDef({ ORIGIN_TELEPHONY, ORIGIN_MANUAL, ORIGIN_NETWORK, ORIGIN_GNSS })
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@interface Origin {}
|
||||
|
||||
@@ -56,6 +57,10 @@ public interface TimeDetectorStrategy {
|
||||
@Origin
|
||||
int ORIGIN_NETWORK = 3;
|
||||
|
||||
/** Used when a time value originated from a gnss signal. */
|
||||
@Origin
|
||||
int ORIGIN_GNSS = 4;
|
||||
|
||||
/** Processes the suggested time from telephony sources. */
|
||||
void suggestTelephonyTime(@NonNull TelephonyTimeSuggestion timeSuggestion);
|
||||
|
||||
@@ -70,6 +75,9 @@ public interface TimeDetectorStrategy {
|
||||
/** Processes the suggested time from network sources. */
|
||||
void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSuggestion);
|
||||
|
||||
/** Processes the suggested time from gnss sources. */
|
||||
void suggestGnssTime(@NonNull GnssTimeSuggestion timeSuggestion);
|
||||
|
||||
/**
|
||||
* Handles the auto-time configuration changing For example, when the auto-time setting is
|
||||
* toggled on or off.
|
||||
@@ -102,6 +110,8 @@ public interface TimeDetectorStrategy {
|
||||
return "network";
|
||||
case ORIGIN_TELEPHONY:
|
||||
return "telephony";
|
||||
case ORIGIN_GNSS:
|
||||
return "gnss";
|
||||
default:
|
||||
throw new IllegalArgumentException("origin=" + origin);
|
||||
}
|
||||
@@ -119,6 +129,8 @@ public interface TimeDetectorStrategy {
|
||||
return ORIGIN_NETWORK;
|
||||
case "telephony":
|
||||
return ORIGIN_TELEPHONY;
|
||||
case "gnss":
|
||||
return ORIGIN_GNSS;
|
||||
default:
|
||||
throw new IllegalArgumentException("originString=" + originString);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import static java.util.stream.Collectors.joining;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.AlarmManager;
|
||||
import android.app.timedetector.GnssTimeSuggestion;
|
||||
import android.app.timedetector.ManualTimeSuggestion;
|
||||
import android.app.timedetector.NetworkTimeSuggestion;
|
||||
import android.app.timedetector.TelephonyTimeSuggestion;
|
||||
@@ -109,6 +110,10 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
|
||||
private final ReferenceWithHistory<NetworkTimeSuggestion> mLastNetworkSuggestion =
|
||||
new ReferenceWithHistory<>(KEEP_SUGGESTION_HISTORY_SIZE);
|
||||
|
||||
@GuardedBy("this")
|
||||
private final ReferenceWithHistory<GnssTimeSuggestion> mLastGnssSuggestion =
|
||||
new ReferenceWithHistory<>(KEEP_SUGGESTION_HISTORY_SIZE);
|
||||
|
||||
/**
|
||||
* The interface used by the strategy to interact with the surrounding service.
|
||||
*
|
||||
@@ -165,6 +170,20 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void suggestGnssTime(@NonNull GnssTimeSuggestion timeSuggestion) {
|
||||
final TimestampedValue<Long> newUtcTime = timeSuggestion.getUtcTime();
|
||||
|
||||
if (!validateAutoSuggestionTime(newUtcTime, timeSuggestion)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mLastGnssSuggestion.set(timeSuggestion);
|
||||
|
||||
String reason = "GNSS time suggestion received: suggestion=" + timeSuggestion;
|
||||
doAutoTimeDetection(reason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean suggestManualTime(@NonNull ManualTimeSuggestion suggestion) {
|
||||
final TimestampedValue<Long> newUtcTime = suggestion.getUtcTime();
|
||||
@@ -280,6 +299,11 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
|
||||
mLastNetworkSuggestion.dump(ipw);
|
||||
ipw.decreaseIndent(); // level 2
|
||||
|
||||
ipw.println("Gnss suggestion history:");
|
||||
ipw.increaseIndent(); // level 2
|
||||
mLastGnssSuggestion.dump(ipw);
|
||||
ipw.decreaseIndent(); // level 2
|
||||
|
||||
ipw.decreaseIndent(); // level 1
|
||||
ipw.flush();
|
||||
}
|
||||
@@ -386,6 +410,14 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
|
||||
+ ", networkSuggestion=" + networkSuggestion
|
||||
+ ", detectionReason=" + detectionReason;
|
||||
}
|
||||
} else if (origin == ORIGIN_GNSS) {
|
||||
GnssTimeSuggestion gnssTimeSuggestion = findLatestValidGnssSuggestion();
|
||||
if (gnssTimeSuggestion != null) {
|
||||
newUtcTime = gnssTimeSuggestion.getUtcTime();
|
||||
cause = "Found good gnss suggestion."
|
||||
+ ", gnssTimeSuggestion=" + gnssTimeSuggestion
|
||||
+ ", detectionReason=" + detectionReason;
|
||||
}
|
||||
} else {
|
||||
Slog.w(LOG_TAG, "Unknown or unsupported origin=" + origin
|
||||
+ " in " + Arrays.toString(originPriorities)
|
||||
@@ -527,6 +559,26 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
|
||||
return networkSuggestion;
|
||||
}
|
||||
|
||||
/** Returns the latest, valid, gnss suggestion. Returns {@code null} if there isn't one. */
|
||||
@GuardedBy("this")
|
||||
@Nullable
|
||||
private GnssTimeSuggestion findLatestValidGnssSuggestion() {
|
||||
GnssTimeSuggestion gnssTimeSuggestion = mLastGnssSuggestion.get();
|
||||
if (gnssTimeSuggestion == null) {
|
||||
// No gnss suggestions received. This is normal if there's no gnss signal.
|
||||
return null;
|
||||
}
|
||||
|
||||
TimestampedValue<Long> utcTime = gnssTimeSuggestion.getUtcTime();
|
||||
long elapsedRealTimeMillis = mCallback.elapsedRealtimeMillis();
|
||||
if (!validateSuggestionUtcTime(elapsedRealTimeMillis, utcTime)) {
|
||||
// The latest suggestion is not valid, usually due to its age.
|
||||
return null;
|
||||
}
|
||||
|
||||
return gnssTimeSuggestion;
|
||||
}
|
||||
|
||||
@GuardedBy("this")
|
||||
private boolean setSystemClockIfRequired(
|
||||
@Origin int origin, @NonNull TimestampedValue<Long> time, @NonNull String cause) {
|
||||
@@ -654,6 +706,16 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
|
||||
return findLatestValidNetworkSuggestion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the latest valid gnss suggestion. Not intended for general use: it is used during
|
||||
* tests to check strategy behavior.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
@Nullable
|
||||
public synchronized GnssTimeSuggestion findLatestValidGnssSuggestionForTests() {
|
||||
return findLatestValidGnssSuggestion();
|
||||
}
|
||||
|
||||
/**
|
||||
* A method used to inspect state during tests. Not intended for general use.
|
||||
*/
|
||||
@@ -672,6 +734,15 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
|
||||
return mLastNetworkSuggestion.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* A method used to inspect state during tests. Not intended for general use.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
@Nullable
|
||||
public synchronized GnssTimeSuggestion getLatestGnssSuggestion() {
|
||||
return mLastGnssSuggestion.get();
|
||||
}
|
||||
|
||||
private static boolean validateSuggestionUtcTime(
|
||||
long elapsedRealtimeMillis, TimestampedValue<Long> utcTime) {
|
||||
long referenceTimeMillis = utcTime.getReferenceTimeMillis();
|
||||
|
||||
@@ -28,6 +28,7 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.timedetector.GnssTimeSuggestion;
|
||||
import android.app.timedetector.ManualTimeSuggestion;
|
||||
import android.app.timedetector.NetworkTimeSuggestion;
|
||||
import android.app.timedetector.TelephonyTimeSuggestion;
|
||||
@@ -172,6 +173,36 @@ public class TimeDetectorServiceTest {
|
||||
mStubbedTimeDetectorStrategy.verifySuggestNetworkTimeCalled(NetworkTimeSuggestion);
|
||||
}
|
||||
|
||||
@Test(expected = SecurityException.class)
|
||||
public void testSuggestGnssTime_withoutPermission() {
|
||||
doThrow(new SecurityException("Mock"))
|
||||
.when(mMockContext).enforceCallingOrSelfPermission(anyString(), any());
|
||||
GnssTimeSuggestion gnssTimeSuggestion = createGnssTimeSuggestion();
|
||||
|
||||
try {
|
||||
mTimeDetectorService.suggestGnssTime(gnssTimeSuggestion);
|
||||
fail();
|
||||
} finally {
|
||||
verify(mMockContext).enforceCallingOrSelfPermission(
|
||||
eq(android.Manifest.permission.SET_TIME), anyString());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuggestGnssTime() throws Exception {
|
||||
doNothing().when(mMockContext).enforceCallingOrSelfPermission(anyString(), any());
|
||||
|
||||
GnssTimeSuggestion gnssTimeSuggestion = createGnssTimeSuggestion();
|
||||
mTimeDetectorService.suggestGnssTime(gnssTimeSuggestion);
|
||||
mTestHandler.assertTotalMessagesEnqueued(1);
|
||||
|
||||
verify(mMockContext).enforceCallingOrSelfPermission(
|
||||
eq(android.Manifest.permission.SET_TIME), anyString());
|
||||
|
||||
mTestHandler.waitForMessagesToBeProcessed();
|
||||
mStubbedTimeDetectorStrategy.verifySuggestGnssTimeCalled(gnssTimeSuggestion);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDump() {
|
||||
when(mMockContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP))
|
||||
@@ -216,12 +247,18 @@ public class TimeDetectorServiceTest {
|
||||
return new NetworkTimeSuggestion(timeValue);
|
||||
}
|
||||
|
||||
private static GnssTimeSuggestion createGnssTimeSuggestion() {
|
||||
TimestampedValue<Long> timeValue = new TimestampedValue<>(100L, 1_000_000L);
|
||||
return new GnssTimeSuggestion(timeValue);
|
||||
}
|
||||
|
||||
private static class StubbedTimeDetectorStrategy implements TimeDetectorStrategy {
|
||||
|
||||
// Call tracking.
|
||||
private TelephonyTimeSuggestion mLastTelephonySuggestion;
|
||||
private ManualTimeSuggestion mLastManualSuggestion;
|
||||
private NetworkTimeSuggestion mLastNetworkSuggestion;
|
||||
private GnssTimeSuggestion mLastGnssSuggestion;
|
||||
private boolean mHandleAutoTimeDetectionChangedCalled;
|
||||
private boolean mDumpCalled;
|
||||
|
||||
@@ -241,6 +278,11 @@ public class TimeDetectorServiceTest {
|
||||
mLastNetworkSuggestion = timeSuggestion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suggestGnssTime(GnssTimeSuggestion timeSuggestion) {
|
||||
mLastGnssSuggestion = timeSuggestion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleAutoTimeConfigChanged() {
|
||||
mHandleAutoTimeDetectionChangedCalled = true;
|
||||
@@ -255,6 +297,7 @@ public class TimeDetectorServiceTest {
|
||||
mLastTelephonySuggestion = null;
|
||||
mLastManualSuggestion = null;
|
||||
mLastNetworkSuggestion = null;
|
||||
mLastGnssSuggestion = null;
|
||||
mHandleAutoTimeDetectionChangedCalled = false;
|
||||
mDumpCalled = false;
|
||||
}
|
||||
@@ -271,6 +314,10 @@ public class TimeDetectorServiceTest {
|
||||
assertEquals(expectedSuggestion, mLastNetworkSuggestion);
|
||||
}
|
||||
|
||||
void verifySuggestGnssTimeCalled(GnssTimeSuggestion expectedSuggestion) {
|
||||
assertEquals(expectedSuggestion, mLastGnssSuggestion);
|
||||
}
|
||||
|
||||
void verifyHandleAutoTimeDetectionChangedCalled() {
|
||||
assertTrue(mHandleAutoTimeDetectionChangedCalled);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server.timedetector;
|
||||
|
||||
import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_GNSS;
|
||||
import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_NETWORK;
|
||||
import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_TELEPHONY;
|
||||
|
||||
@@ -25,6 +26,7 @@ import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import android.app.timedetector.GnssTimeSuggestion;
|
||||
import android.app.timedetector.ManualTimeSuggestion;
|
||||
import android.app.timedetector.NetworkTimeSuggestion;
|
||||
import android.app.timedetector.TelephonyTimeSuggestion;
|
||||
@@ -569,7 +571,53 @@ public class TimeDetectorStrategyImplTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void highPrioritySuggestionsShouldBeatLowerPrioritySuggestions() {
|
||||
public void testSuggestGnssTime_autoTimeEnabled() {
|
||||
mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
|
||||
.pokeAutoOriginPriorities(ORIGIN_GNSS)
|
||||
.pokeAutoTimeDetectionEnabled(true);
|
||||
|
||||
GnssTimeSuggestion timeSuggestion =
|
||||
mScript.generateGnssTimeSuggestion(ARBITRARY_TEST_TIME);
|
||||
|
||||
mScript.simulateTimePassing();
|
||||
|
||||
long expectedSystemClockMillis =
|
||||
mScript.calculateTimeInMillisForNow(timeSuggestion.getUtcTime());
|
||||
mScript.simulateGnssTimeSuggestion(timeSuggestion)
|
||||
.verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuggestGnssTime_autoTimeDisabled() {
|
||||
mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
|
||||
.pokeAutoOriginPriorities(ORIGIN_GNSS)
|
||||
.pokeAutoTimeDetectionEnabled(false);
|
||||
|
||||
GnssTimeSuggestion timeSuggestion =
|
||||
mScript.generateGnssTimeSuggestion(ARBITRARY_TEST_TIME);
|
||||
|
||||
mScript.simulateTimePassing()
|
||||
.simulateGnssTimeSuggestion(timeSuggestion)
|
||||
.verifySystemClockWasNotSetAndResetCallTracking();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void gnssTimeSuggestion_ignoredWhenReferencedTimeIsInThePast() {
|
||||
mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
|
||||
.pokeAutoOriginPriorities(ORIGIN_GNSS)
|
||||
.pokeAutoTimeDetectionEnabled(true);
|
||||
|
||||
Instant suggestedTime = TIME_LOWER_BOUND.minus(Duration.ofDays(1));
|
||||
GnssTimeSuggestion timeSuggestion = mScript
|
||||
.generateGnssTimeSuggestion(suggestedTime);
|
||||
|
||||
mScript.simulateGnssTimeSuggestion(timeSuggestion)
|
||||
.verifySystemClockWasNotSetAndResetCallTracking()
|
||||
.assertLatestGnssSuggestion(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void highPrioritySuggestionsBeatLowerPrioritySuggestions_telephonyNetworkOrigins() {
|
||||
mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
|
||||
.pokeAutoTimeDetectionEnabled(true)
|
||||
.pokeAutoOriginPriorities(ORIGIN_TELEPHONY, ORIGIN_NETWORK);
|
||||
@@ -671,23 +719,131 @@ public class TimeDetectorStrategyImplTest {
|
||||
mScript.peekBestTelephonySuggestion());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void highPrioritySuggestionsBeatLowerPrioritySuggestions_networkGnssOrigins() {
|
||||
mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
|
||||
.pokeAutoTimeDetectionEnabled(true)
|
||||
.pokeAutoOriginPriorities(ORIGIN_NETWORK, ORIGIN_GNSS);
|
||||
|
||||
// Three obviously different times that could not be mistaken for each other.
|
||||
Instant gnssTime1 = ARBITRARY_TEST_TIME;
|
||||
Instant gnssTime2 = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30));
|
||||
Instant networkTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(60));
|
||||
// A small increment used to simulate the passage of time, but not enough to interfere with
|
||||
// macro-level time changes associated with suggestion age.
|
||||
final long smallTimeIncrementMillis = 101;
|
||||
|
||||
// A gnss suggestion is made. It should be used because there is no network suggestion.
|
||||
GnssTimeSuggestion gnssTimeSuggestion1 =
|
||||
mScript.generateGnssTimeSuggestion(gnssTime1);
|
||||
mScript.simulateTimePassing(smallTimeIncrementMillis)
|
||||
.simulateGnssTimeSuggestion(gnssTimeSuggestion1)
|
||||
.verifySystemClockWasSetAndResetCallTracking(
|
||||
mScript.calculateTimeInMillisForNow(gnssTimeSuggestion1.getUtcTime()));
|
||||
|
||||
// Check internal state.
|
||||
mScript.assertLatestNetworkSuggestion(null)
|
||||
.assertLatestGnssSuggestion(gnssTimeSuggestion1);
|
||||
assertEquals(gnssTimeSuggestion1, mScript.peekLatestValidGnssSuggestion());
|
||||
assertNull("No network suggestions were made:", mScript.peekLatestValidNetworkSuggestion());
|
||||
|
||||
// Simulate a little time passing.
|
||||
mScript.simulateTimePassing(smallTimeIncrementMillis)
|
||||
.verifySystemClockWasNotSetAndResetCallTracking();
|
||||
|
||||
// Now a network suggestion is made. Network suggestions are prioritized over gnss
|
||||
// suggestions so it should "win".
|
||||
NetworkTimeSuggestion networkTimeSuggestion =
|
||||
mScript.generateNetworkTimeSuggestion(networkTime);
|
||||
mScript.simulateTimePassing(smallTimeIncrementMillis)
|
||||
.simulateNetworkTimeSuggestion(networkTimeSuggestion)
|
||||
.verifySystemClockWasSetAndResetCallTracking(
|
||||
mScript.calculateTimeInMillisForNow(networkTimeSuggestion.getUtcTime()));
|
||||
|
||||
// Check internal state.
|
||||
mScript.assertLatestNetworkSuggestion(networkTimeSuggestion)
|
||||
.assertLatestGnssSuggestion(gnssTimeSuggestion1);
|
||||
assertEquals(gnssTimeSuggestion1, mScript.peekLatestValidGnssSuggestion());
|
||||
assertEquals(networkTimeSuggestion, mScript.peekLatestValidNetworkSuggestion());
|
||||
|
||||
// Simulate some significant time passing: half the time allowed before a time signal
|
||||
// becomes "too old to use".
|
||||
mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_UTC_TIME_AGE_MILLIS / 2)
|
||||
.verifySystemClockWasNotSetAndResetCallTracking();
|
||||
|
||||
// Now another gnss suggestion is made. Network suggestions are prioritized over
|
||||
// gnss suggestions so the latest network suggestion should still "win".
|
||||
GnssTimeSuggestion gnssTimeSuggestion2 =
|
||||
mScript.generateGnssTimeSuggestion(gnssTime2);
|
||||
mScript.simulateTimePassing(smallTimeIncrementMillis)
|
||||
.simulateGnssTimeSuggestion(gnssTimeSuggestion2)
|
||||
.verifySystemClockWasNotSetAndResetCallTracking();
|
||||
|
||||
// Check internal state.
|
||||
mScript.assertLatestNetworkSuggestion(networkTimeSuggestion)
|
||||
.assertLatestGnssSuggestion(gnssTimeSuggestion2);
|
||||
assertEquals(gnssTimeSuggestion2, mScript.peekLatestValidGnssSuggestion());
|
||||
assertEquals(networkTimeSuggestion, mScript.peekLatestValidNetworkSuggestion());
|
||||
|
||||
// Simulate some significant time passing: half the time allowed before a time signal
|
||||
// becomes "too old to use". This should mean that telephonyTimeSuggestion is now too old to
|
||||
// be used but networkTimeSuggestion2 is not.
|
||||
mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_UTC_TIME_AGE_MILLIS / 2);
|
||||
|
||||
// NOTE: The TimeDetectorStrategyImpl doesn't set an alarm for the point when the last
|
||||
// suggestion it used becomes too old: it requires a new suggestion or an auto-time toggle
|
||||
// to re-run the detection logic. This may change in future but until then we rely on a
|
||||
// steady stream of suggestions to re-evaluate.
|
||||
mScript.verifySystemClockWasNotSetAndResetCallTracking();
|
||||
|
||||
// Check internal state.
|
||||
mScript.assertLatestNetworkSuggestion(networkTimeSuggestion)
|
||||
.assertLatestGnssSuggestion(gnssTimeSuggestion2);
|
||||
assertEquals(gnssTimeSuggestion2, mScript.peekLatestValidGnssSuggestion());
|
||||
assertNull(
|
||||
"Network suggestion should be expired:",
|
||||
mScript.peekLatestValidNetworkSuggestion());
|
||||
|
||||
// Toggle auto-time off and on to force the detection logic to run.
|
||||
mScript.simulateAutoTimeDetectionToggle()
|
||||
.simulateTimePassing(smallTimeIncrementMillis)
|
||||
.simulateAutoTimeDetectionToggle();
|
||||
|
||||
// Verify the latest gnss time now wins.
|
||||
mScript.verifySystemClockWasSetAndResetCallTracking(
|
||||
mScript.calculateTimeInMillisForNow(gnssTimeSuggestion2.getUtcTime()));
|
||||
|
||||
// Check internal state.
|
||||
mScript.assertLatestNetworkSuggestion(networkTimeSuggestion)
|
||||
.assertLatestGnssSuggestion(gnssTimeSuggestion2);
|
||||
assertEquals(gnssTimeSuggestion2, mScript.peekLatestValidGnssSuggestion());
|
||||
assertNull(
|
||||
"Network suggestion should still be expired:",
|
||||
mScript.peekLatestValidNetworkSuggestion());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAllTimeSuggestionsAreAvailable_higherPriorityWins_lowerPriorityComesFirst() {
|
||||
mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
|
||||
.pokeAutoTimeDetectionEnabled(true)
|
||||
.pokeAutoOriginPriorities(ORIGIN_TELEPHONY, ORIGIN_NETWORK);
|
||||
.pokeAutoOriginPriorities(ORIGIN_TELEPHONY, ORIGIN_NETWORK, ORIGIN_GNSS);
|
||||
|
||||
Instant networkTime = ARBITRARY_TEST_TIME;
|
||||
Instant telephonyTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30));
|
||||
Instant gnssTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30));
|
||||
Instant telephonyTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(60));
|
||||
|
||||
NetworkTimeSuggestion networkTimeSuggestion =
|
||||
mScript.generateNetworkTimeSuggestion(networkTime);
|
||||
GnssTimeSuggestion gnssTimeSuggestion =
|
||||
mScript.generateGnssTimeSuggestion(gnssTime);
|
||||
TelephonyTimeSuggestion telephonyTimeSuggestion =
|
||||
mScript.generateTelephonyTimeSuggestion(ARBITRARY_SLOT_INDEX, telephonyTime);
|
||||
|
||||
mScript.simulateNetworkTimeSuggestion(networkTimeSuggestion)
|
||||
.simulateGnssTimeSuggestion(gnssTimeSuggestion)
|
||||
.simulateTelephonyTimeSuggestion(telephonyTimeSuggestion)
|
||||
.assertLatestNetworkSuggestion(networkTimeSuggestion)
|
||||
.assertLatestGnssSuggestion(gnssTimeSuggestion)
|
||||
.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion)
|
||||
.verifySystemClockWasSetAndResetCallTracking(telephonyTime.toEpochMilli());
|
||||
}
|
||||
@@ -696,20 +852,25 @@ public class TimeDetectorStrategyImplTest {
|
||||
public void whenAllTimeSuggestionsAreAvailable_higherPriorityWins_higherPriorityComesFirst() {
|
||||
mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
|
||||
.pokeAutoTimeDetectionEnabled(true)
|
||||
.pokeAutoOriginPriorities(ORIGIN_TELEPHONY, ORIGIN_NETWORK);
|
||||
.pokeAutoOriginPriorities(ORIGIN_TELEPHONY, ORIGIN_NETWORK, ORIGIN_GNSS);
|
||||
|
||||
Instant networkTime = ARBITRARY_TEST_TIME;
|
||||
Instant telephonyTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30));
|
||||
Instant gnssTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(60));
|
||||
|
||||
NetworkTimeSuggestion networkTimeSuggestion =
|
||||
mScript.generateNetworkTimeSuggestion(networkTime);
|
||||
TelephonyTimeSuggestion telephonyTimeSuggestion =
|
||||
mScript.generateTelephonyTimeSuggestion(ARBITRARY_SLOT_INDEX, telephonyTime);
|
||||
GnssTimeSuggestion gnssTimeSuggestion =
|
||||
mScript.generateGnssTimeSuggestion(gnssTime);
|
||||
|
||||
mScript.simulateTelephonyTimeSuggestion(telephonyTimeSuggestion)
|
||||
.simulateNetworkTimeSuggestion(networkTimeSuggestion)
|
||||
.simulateGnssTimeSuggestion(gnssTimeSuggestion)
|
||||
.assertLatestNetworkSuggestion(networkTimeSuggestion)
|
||||
.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion)
|
||||
.assertLatestGnssSuggestion(gnssTimeSuggestion)
|
||||
.verifySystemClockWasSetAndResetCallTracking(telephonyTime.toEpochMilli());
|
||||
}
|
||||
|
||||
@@ -728,7 +889,37 @@ public class TimeDetectorStrategyImplTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void suggestionsFromSourceNotListedInPrioritiesList_areIgnored() {
|
||||
public void whenHigherPrioritySuggestionsAreNotAvailable_fallbacksToNext() {
|
||||
mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
|
||||
.pokeAutoTimeDetectionEnabled(true)
|
||||
.pokeAutoOriginPriorities(ORIGIN_TELEPHONY, ORIGIN_NETWORK, ORIGIN_GNSS);
|
||||
|
||||
GnssTimeSuggestion timeSuggestion =
|
||||
mScript.generateGnssTimeSuggestion(ARBITRARY_TEST_TIME);
|
||||
|
||||
mScript.simulateGnssTimeSuggestion(timeSuggestion)
|
||||
.assertLatestGnssSuggestion(timeSuggestion)
|
||||
.verifySystemClockWasSetAndResetCallTracking(ARBITRARY_TEST_TIME.toEpochMilli());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void suggestionsFromTelephonyOriginNotInPriorityList_areIgnored() {
|
||||
mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
|
||||
.pokeAutoTimeDetectionEnabled(true)
|
||||
.pokeAutoOriginPriorities(ORIGIN_NETWORK);
|
||||
|
||||
int slotIndex = ARBITRARY_SLOT_INDEX;
|
||||
Instant testTime = ARBITRARY_TEST_TIME;
|
||||
TelephonyTimeSuggestion timeSuggestion =
|
||||
mScript.generateTelephonyTimeSuggestion(slotIndex, testTime);
|
||||
|
||||
mScript.simulateTelephonyTimeSuggestion(timeSuggestion)
|
||||
.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, timeSuggestion)
|
||||
.verifySystemClockWasNotSetAndResetCallTracking();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void suggestionsFromNetworkOriginNotInPriorityList_areIgnored() {
|
||||
mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
|
||||
.pokeAutoTimeDetectionEnabled(true)
|
||||
.pokeAutoOriginPriorities(ORIGIN_TELEPHONY);
|
||||
@@ -741,6 +932,20 @@ public class TimeDetectorStrategyImplTest {
|
||||
.verifySystemClockWasNotSetAndResetCallTracking();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void suggestionsFromGnssOriginNotInPriorityList_areIgnored() {
|
||||
mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
|
||||
.pokeAutoTimeDetectionEnabled(true)
|
||||
.pokeAutoOriginPriorities(ORIGIN_TELEPHONY);
|
||||
|
||||
GnssTimeSuggestion timeSuggestion = mScript.generateGnssTimeSuggestion(
|
||||
ARBITRARY_TEST_TIME);
|
||||
|
||||
mScript.simulateGnssTimeSuggestion(timeSuggestion)
|
||||
.assertLatestGnssSuggestion(timeSuggestion)
|
||||
.verifySystemClockWasNotSetAndResetCallTracking();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void autoOriginPrioritiesList_doesNotAffectManualSuggestion() {
|
||||
mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
|
||||
@@ -945,6 +1150,11 @@ public class TimeDetectorStrategyImplTest {
|
||||
return this;
|
||||
}
|
||||
|
||||
Script simulateGnssTimeSuggestion(GnssTimeSuggestion timeSuggestion) {
|
||||
mTimeDetectorStrategy.suggestGnssTime(timeSuggestion);
|
||||
return this;
|
||||
}
|
||||
|
||||
Script simulateAutoTimeDetectionToggle() {
|
||||
mFakeCallback.simulateAutoTimeZoneDetectionToggle();
|
||||
mTimeDetectorStrategy.handleAutoTimeConfigChanged();
|
||||
@@ -994,6 +1204,14 @@ public class TimeDetectorStrategyImplTest {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* White box test info: Asserts the latest gnss suggestion is as expected.
|
||||
*/
|
||||
Script assertLatestGnssSuggestion(GnssTimeSuggestion expected) {
|
||||
assertEquals(expected, mTimeDetectorStrategy.getLatestGnssSuggestion());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* White box test info: Returns the telephony suggestion that would be used, if any, given
|
||||
* the current elapsed real time clock and regardless of origin prioritization.
|
||||
@@ -1010,6 +1228,14 @@ public class TimeDetectorStrategyImplTest {
|
||||
return mTimeDetectorStrategy.findLatestValidNetworkSuggestionForTests();
|
||||
}
|
||||
|
||||
/**
|
||||
* White box test info: Returns the gnss suggestion that would be used, if any, given the
|
||||
* current elapsed real time clock and regardless of origin prioritization.
|
||||
*/
|
||||
GnssTimeSuggestion peekLatestValidGnssSuggestion() {
|
||||
return mTimeDetectorStrategy.findLatestValidGnssSuggestionForTests();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a ManualTimeSuggestion using the current elapsed realtime clock for the
|
||||
* reference time.
|
||||
@@ -1056,6 +1282,18 @@ public class TimeDetectorStrategyImplTest {
|
||||
return new NetworkTimeSuggestion(utcTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a GnssTimeSuggestion using the current elapsed realtime clock for the
|
||||
* reference time.
|
||||
*/
|
||||
GnssTimeSuggestion generateGnssTimeSuggestion(Instant suggestedTime) {
|
||||
TimestampedValue<Long> utcTime =
|
||||
new TimestampedValue<>(
|
||||
mFakeCallback.peekElapsedRealtimeMillis(),
|
||||
suggestedTime.toEpochMilli());
|
||||
return new GnssTimeSuggestion(utcTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates what the supplied time would be when adjusted for the movement of the fake
|
||||
* elapsed realtime clock.
|
||||
|
||||
Reference in New Issue
Block a user