summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/timedetector/TimeDetector.java14
-rw-r--r--core/java/android/util/NtpTrustedTime.java9
-rw-r--r--services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java18
-rw-r--r--services/core/java/com/android/server/timedetector/NetworkTimeUpdateServiceShellCommand.java14
-rw-r--r--services/core/java/com/android/server/timedetector/TimeDetectorService.java96
-rw-r--r--services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java40
-rw-r--r--services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java47
7 files changed, 153 insertions, 85 deletions
diff --git a/core/java/android/app/timedetector/TimeDetector.java b/core/java/android/app/timedetector/TimeDetector.java
index 50a7da1cede5..5ee10a50568d 100644
--- a/core/java/android/app/timedetector/TimeDetector.java
+++ b/core/java/android/app/timedetector/TimeDetector.java
@@ -115,6 +115,20 @@ public interface TimeDetector {
String SHELL_COMMAND_CONFIRM_TIME = "confirm_time";
/**
+ * A shell command that clears the network time signal used by {@link
+ * SystemClock#currentNetworkTimeClock()}.
+ * @hide
+ */
+ String SHELL_COMMAND_CLEAR_SYSTEM_CLOCK_NETWORK_TIME = "clear_system_clock_network_time";
+
+ /**
+ * A shell command that sets the network time signal used by {@link
+ * SystemClock#currentNetworkTimeClock()}.
+ * @hide
+ */
+ String SHELL_COMMAND_SET_SYSTEM_CLOCK_NETWORK_TIME = "set_system_clock_network_time";
+
+ /**
* A shared utility method to create a {@link ManualTimeSuggestion}.
*
* @hide
diff --git a/core/java/android/util/NtpTrustedTime.java b/core/java/android/util/NtpTrustedTime.java
index 98c0d7f4fbf1..5aa0f59024f8 100644
--- a/core/java/android/util/NtpTrustedTime.java
+++ b/core/java/android/util/NtpTrustedTime.java
@@ -477,7 +477,14 @@ public abstract class NtpTrustedTime implements TrustedTime {
return mTimeResult;
}
- /** Clears the last received NTP. Intended for use during tests. */
+ /** Sets the last received NTP time. Intended for use during tests. */
+ public void setCachedTimeResult(TimeResult timeResult) {
+ synchronized (this) {
+ mTimeResult = timeResult;
+ }
+ }
+
+ /** Clears the last received NTP time. Intended for use during tests. */
public void clearCachedTimeResult() {
synchronized (this) {
mTimeResult = null;
diff --git a/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java b/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java
index 080929729fe3..a3ba7373b921 100644
--- a/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java
+++ b/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java
@@ -181,24 +181,6 @@ public class NetworkTimeUpdateService extends Binder {
}
/**
- * Clears the cached NTP time. For use during tests to simulate when no NTP time is available.
- *
- * <p>This operation takes place in the calling thread rather than the service's handler thread.
- */
- @RequiresPermission(android.Manifest.permission.SET_TIME)
- void clearTimeForTests() {
- mContext.enforceCallingPermission(
- android.Manifest.permission.SET_TIME, "clear latest network time");
-
- final long token = Binder.clearCallingIdentity();
- try {
- mNtpTrustedTime.clearCachedTimeResult();
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /**
* Forces the service to refresh the NTP time.
*
* <p>This operation takes place in the calling thread rather than the service's handler thread.
diff --git a/services/core/java/com/android/server/timedetector/NetworkTimeUpdateServiceShellCommand.java b/services/core/java/com/android/server/timedetector/NetworkTimeUpdateServiceShellCommand.java
index 410b50f8a88b..b19ce59dc2f5 100644
--- a/services/core/java/com/android/server/timedetector/NetworkTimeUpdateServiceShellCommand.java
+++ b/services/core/java/com/android/server/timedetector/NetworkTimeUpdateServiceShellCommand.java
@@ -37,11 +37,6 @@ class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
private static final String SHELL_COMMAND_SERVICE_NAME = "network_time_update_service";
/**
- * A shell command that clears the time signal received from the network.
- */
- private static final String SHELL_COMMAND_CLEAR_TIME = "clear_time";
-
- /**
* A shell command that forces the time signal to be refreshed from the network.
*/
private static final String SHELL_COMMAND_FORCE_REFRESH = "force_refresh";
@@ -73,8 +68,6 @@ class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
}
switch (cmd) {
- case SHELL_COMMAND_CLEAR_TIME:
- return runClearTime();
case SHELL_COMMAND_FORCE_REFRESH:
return runForceRefresh();
case SHELL_COMMAND_SET_SERVER_CONFIG:
@@ -87,11 +80,6 @@ class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
}
}
- private int runClearTime() {
- mNetworkTimeUpdateService.clearTimeForTests();
- return 0;
- }
-
private int runForceRefresh() {
boolean success = mNetworkTimeUpdateService.forceRefreshForTests();
getOutPrintWriter().println(success);
@@ -147,8 +135,6 @@ class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
pw.printf("Network Time Update Service (%s) commands:\n", SHELL_COMMAND_SERVICE_NAME);
pw.printf(" help\n");
pw.printf(" Print this help text.\n");
- pw.printf(" %s\n", SHELL_COMMAND_CLEAR_TIME);
- pw.printf(" Clears the latest time.\n");
pw.printf(" %s\n", SHELL_COMMAND_FORCE_REFRESH);
pw.printf(" Refreshes the latest time. Prints whether it was successful.\n");
pw.printf(" %s\n", SHELL_COMMAND_SET_SERVER_CONFIG);
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorService.java b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
index 0da967a3bc00..22f096b11f18 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorService.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
@@ -37,6 +37,7 @@ import android.os.ParcelableException;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ShellCallback;
+import android.os.SystemClock;
import android.util.ArrayMap;
import android.util.IndentingPrintWriter;
import android.util.NtpTrustedTime;
@@ -53,6 +54,7 @@ import com.android.server.timezonedetector.CurrentUserIdentityInjector;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.net.InetSocketAddress;
import java.time.DateTimeException;
import java.util.Objects;
@@ -377,7 +379,7 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub
*
* <p>This operation takes place in the calling thread.
*/
- void clearNetworkTime() {
+ void clearLatestNetworkTime() {
enforceSuggestNetworkTimePermission();
final long token = Binder.clearCallingIdentity();
@@ -390,12 +392,29 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub
@Override
public UnixEpochTime latestNetworkTime() {
- NetworkTimeSuggestion suggestion = getLatestNetworkSuggestion();
- if (suggestion != null) {
- return suggestion.getUnixEpochTime();
+ NetworkTimeSuggestion latestNetworkTime;
+ // TODO(b/222295093): Remove this condition once we can be sure that all uses of
+ // NtpTrustedTime result in a suggestion being made to the time detector.
+ // mNtpTrustedTime can be removed once this happens.
+ if (TimeDetectorNetworkTimeHelper.isInUse()) {
+ // The new implementation.
+ latestNetworkTime = mTimeDetectorStrategy.getLatestNetworkSuggestion();
} else {
+ // The old implementation.
+ NtpTrustedTime.TimeResult ntpResult = mNtpTrustedTime.getCachedTimeResult();
+ if (ntpResult != null) {
+ latestNetworkTime = new NetworkTimeSuggestion(
+ new UnixEpochTime(
+ ntpResult.getElapsedRealtimeMillis(), ntpResult.getTimeMillis()),
+ ntpResult.getUncertaintyMillis());
+ } else {
+ latestNetworkTime = null;
+ }
+ }
+ if (latestNetworkTime == null) {
throw new ParcelableException(new DateTimeException("Missing network time fix"));
}
+ return latestNetworkTime.getUnixEpochTime();
}
/**
@@ -403,23 +422,7 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub
*/
@Nullable
NetworkTimeSuggestion getLatestNetworkSuggestion() {
- // TODO(b/222295093): Return the latest network time from mTimeDetectorStrategy once we can
- // be sure that all uses of NtpTrustedTime results in a suggestion being made to the time
- // detector. mNtpTrustedTime can be removed once this happens.
- if (TimeDetectorNetworkTimeHelper.isInUse()) {
- // The new implementation.
- return mTimeDetectorStrategy.getLatestNetworkSuggestion();
- } else {
- // The old implementation.
- NtpTrustedTime.TimeResult ntpResult = mNtpTrustedTime.getCachedTimeResult();
- if (ntpResult != null) {
- UnixEpochTime unixEpochTime = new UnixEpochTime(
- ntpResult.getElapsedRealtimeMillis(), ntpResult.getTimeMillis());
- return new NetworkTimeSuggestion(unixEpochTime, ntpResult.getUncertaintyMillis());
- } else {
- return null;
- }
- }
+ return mTimeDetectorStrategy.getLatestNetworkSuggestion();
}
/**
@@ -440,6 +443,57 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub
mHandler.post(() -> mTimeDetectorStrategy.suggestExternalTime(timeSignal));
}
+ /**
+ * Sets the network time for testing {@link SystemClock#currentNetworkTimeClock()}.
+ *
+ * <p>This operation takes place in the calling thread.
+ */
+ void setNetworkTimeForSystemClockForTests(
+ @NonNull UnixEpochTime unixEpochTime, int uncertaintyMillis) {
+ enforceSuggestNetworkTimePermission();
+
+ // TODO(b/222295093): Remove this condition once we can be sure that all uses of
+ // NtpTrustedTime result in a suggestion being made to the time detector.
+ // mNtpTrustedTime can be removed once this happens.
+ if (TimeDetectorNetworkTimeHelper.isInUse()) {
+ NetworkTimeSuggestion suggestion =
+ new NetworkTimeSuggestion(unixEpochTime, uncertaintyMillis);
+ suggestion.addDebugInfo("Injected for tests");
+ mTimeDetectorStrategy.suggestNetworkTime(suggestion);
+ } else {
+ NtpTrustedTime.TimeResult timeResult = new NtpTrustedTime.TimeResult(
+ unixEpochTime.getUnixEpochTimeMillis(),
+ unixEpochTime.getElapsedRealtimeMillis(),
+ uncertaintyMillis,
+ InetSocketAddress.createUnresolved("time.set.for.tests", 123));
+ mNtpTrustedTime.setCachedTimeResult(timeResult);
+ }
+ }
+
+ /**
+ * Clears the network time for testing {@link SystemClock#currentNetworkTimeClock()}.
+ *
+ * <p>This operation takes place in the calling thread.
+ */
+ void clearNetworkTimeForSystemClockForTests() {
+ enforceSuggestNetworkTimePermission();
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ // TODO(b/222295093): Remove this condition once we can be sure that all uses of
+ // NtpTrustedTime result in a suggestion being made to the time detector.
+ // mNtpTrustedTime can be removed once this happens.
+ if (TimeDetectorNetworkTimeHelper.isInUse()) {
+ // Clear the latest network suggestion. Done in all c
+ mTimeDetectorStrategy.clearLatestNetworkSuggestion();
+ } else {
+ mNtpTrustedTime.clearCachedTimeResult();
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
@Override
protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw,
@Nullable String[] args) {
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java b/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java
index cce570986168..fe0127fc11f2 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java
@@ -16,12 +16,14 @@
package com.android.server.timedetector;
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_CLEAR_NETWORK_TIME;
+import static android.app.timedetector.TimeDetector.SHELL_COMMAND_CLEAR_SYSTEM_CLOCK_NETWORK_TIME;
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_CONFIRM_TIME;
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_GET_NETWORK_TIME;
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_GET_TIME_STATE;
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_IS_AUTO_DETECTION_ENABLED;
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_SERVICE_NAME;
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_SET_AUTO_DETECTION_ENABLED;
+import static android.app.timedetector.TimeDetector.SHELL_COMMAND_SET_SYSTEM_CLOCK_NETWORK_TIME;
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_SET_TIME_STATE;
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_SUGGEST_EXTERNAL_TIME;
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_SUGGEST_GNSS_TIME;
@@ -73,9 +75,9 @@ class TimeDetectorShellCommand extends ShellCommand {
case SHELL_COMMAND_SUGGEST_NETWORK_TIME:
return runSuggestNetworkTime();
case SHELL_COMMAND_GET_NETWORK_TIME:
- return runGetNetworkTime();
+ return runGetLatestNetworkTime();
case SHELL_COMMAND_CLEAR_NETWORK_TIME:
- return runClearNetworkTime();
+ return runClearLatestNetworkTime();
case SHELL_COMMAND_SUGGEST_GNSS_TIME:
return runSuggestGnssTime();
case SHELL_COMMAND_SUGGEST_EXTERNAL_TIME:
@@ -86,6 +88,10 @@ class TimeDetectorShellCommand extends ShellCommand {
return runSetTimeState();
case SHELL_COMMAND_CONFIRM_TIME:
return runConfirmTime();
+ case SHELL_COMMAND_CLEAR_SYSTEM_CLOCK_NETWORK_TIME:
+ return runClearSystemClockNetworkTime();
+ case SHELL_COMMAND_SET_SYSTEM_CLOCK_NETWORK_TIME:
+ return runSetSystemClockNetworkTime();
default: {
return handleDefaultCommands(cmd);
}
@@ -128,15 +134,15 @@ class TimeDetectorShellCommand extends ShellCommand {
mInterface::suggestNetworkTime);
}
- private int runGetNetworkTime() {
+ private int runGetLatestNetworkTime() {
NetworkTimeSuggestion networkTimeSuggestion = mInterface.getLatestNetworkSuggestion();
final PrintWriter pw = getOutPrintWriter();
pw.println(networkTimeSuggestion);
return 0;
}
- private int runClearNetworkTime() {
- mInterface.clearNetworkTime();
+ private int runClearLatestNetworkTime() {
+ mInterface.clearLatestNetworkTime();
return 0;
}
@@ -187,6 +193,20 @@ class TimeDetectorShellCommand extends ShellCommand {
return 0;
}
+ private int runClearSystemClockNetworkTime() {
+ mInterface.clearNetworkTimeForSystemClockForTests();
+ return 0;
+ }
+
+ private int runSetSystemClockNetworkTime() {
+ NetworkTimeSuggestion networkTimeSuggestion =
+ NetworkTimeSuggestion.parseCommandLineArg(this);
+ mInterface.setNetworkTimeForSystemClockForTests(
+ networkTimeSuggestion.getUnixEpochTime(),
+ networkTimeSuggestion.getUncertaintyMillis());
+ return 0;
+ }
+
@Override
public void onHelp() {
final PrintWriter pw = getOutPrintWriter();
@@ -218,6 +238,16 @@ class TimeDetectorShellCommand extends ShellCommand {
pw.printf(" Prints the network time information held by the detector.\n");
pw.printf(" %s\n", SHELL_COMMAND_CLEAR_NETWORK_TIME);
pw.printf(" Clears the network time information held by the detector.\n");
+ // TODO(b/222295093) Remove these "system_clock" commands when
+ // SystemClock.currentNetworkTimeClock() is guaranteed to use the latest network
+ // suggestion. Then, commands above can be used instead.
+ pw.printf(" %s <network suggestion opts>\n",
+ SHELL_COMMAND_SET_SYSTEM_CLOCK_NETWORK_TIME);
+ pw.printf(" Sets the network time information used for"
+ + " SystemClock.currentNetworkTimeClock().\n");
+ pw.printf(" %s\n", SHELL_COMMAND_CLEAR_SYSTEM_CLOCK_NETWORK_TIME);
+ pw.printf(" Clears the network time information used for"
+ + " SystemClock.currentNetworkTimeClock().\n");
pw.println();
ManualTimeSuggestion.printCommandLineOpts(pw);
pw.println();
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
index 5a0867f8f584..daa682342836 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
@@ -386,16 +386,16 @@ public class TimeDetectorServiceTest {
.when(mMockContext).enforceCallingPermission(anyString(), any());
assertThrows(SecurityException.class,
- () -> mTimeDetectorService.clearNetworkTime());
+ () -> mTimeDetectorService.clearLatestNetworkTime());
verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.SET_TIME), anyString());
}
@Test
- public void testClearNetworkTime() throws Exception {
+ public void testClearLatestNetworkSuggestion() throws Exception {
doNothing().when(mMockContext).enforceCallingPermission(anyString(), any());
- mTimeDetectorService.clearNetworkTime();
+ mTimeDetectorService.clearLatestNetworkTime();
verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.SET_TIME), anyString());
@@ -403,53 +403,48 @@ public class TimeDetectorServiceTest {
}
@Test
- public void testLatestNetworkTime() {
- NtpTrustedTime.TimeResult latestNetworkTime = new NtpTrustedTime.TimeResult(
- 1234L, 54321L, 999, InetSocketAddress.createUnresolved("test.timeserver", 123));
- when(mMockNtpTrustedTime.getCachedTimeResult())
- .thenReturn(latestNetworkTime);
- UnixEpochTime expected = new UnixEpochTime(
- latestNetworkTime.getElapsedRealtimeMillis(), latestNetworkTime.getTimeMillis());
- assertEquals(expected, mTimeDetectorService.latestNetworkTime());
+ public void testGetLatestNetworkSuggestion() {
+ NetworkTimeSuggestion latestNetworkSuggestion = createNetworkTimeSuggestion();
+ mFakeTimeDetectorStrategySpy.setLatestNetworkTime(latestNetworkSuggestion);
+
+ assertEquals(latestNetworkSuggestion, mTimeDetectorService.getLatestNetworkSuggestion());
}
@Test
- public void testLatestNetworkTime_noTimeAvailable() {
- when(mMockNtpTrustedTime.getCachedTimeResult()).thenReturn(null);
- assertThrows(ParcelableException.class, () -> mTimeDetectorService.latestNetworkTime());
+ public void testGetLatestNetworkSuggestion_noTimeAvailable() {
+ mFakeTimeDetectorStrategySpy.setLatestNetworkTime(null);
+
+ assertNull(mTimeDetectorService.getLatestNetworkSuggestion());
}
@Test
- public void testGetLatestNetworkSuggestion() {
+ public void testLatestNetworkTime() {
if (TimeDetectorNetworkTimeHelper.isInUse()) {
- NetworkTimeSuggestion latestNetworkTime = createNetworkTimeSuggestion();
- mFakeTimeDetectorStrategySpy.setLatestNetworkTime(latestNetworkTime);
+ NetworkTimeSuggestion latestNetworkSuggestion = createNetworkTimeSuggestion();
+ mFakeTimeDetectorStrategySpy.setLatestNetworkTime(latestNetworkSuggestion);
- assertEquals(latestNetworkTime, mTimeDetectorService.getLatestNetworkSuggestion());
+ assertEquals(latestNetworkSuggestion.getUnixEpochTime(),
+ mTimeDetectorService.latestNetworkTime());
} else {
NtpTrustedTime.TimeResult latestNetworkTime = new NtpTrustedTime.TimeResult(
1234L, 54321L, 999, InetSocketAddress.createUnresolved("test.timeserver", 123));
when(mMockNtpTrustedTime.getCachedTimeResult())
.thenReturn(latestNetworkTime);
- UnixEpochTime expectedUnixEpochTime = new UnixEpochTime(
+ UnixEpochTime expected = new UnixEpochTime(
latestNetworkTime.getElapsedRealtimeMillis(),
latestNetworkTime.getTimeMillis());
- NetworkTimeSuggestion expected = new NetworkTimeSuggestion(
- expectedUnixEpochTime, latestNetworkTime.getUncertaintyMillis());
- assertEquals(expected, mTimeDetectorService.getLatestNetworkSuggestion());
+ assertEquals(expected, mTimeDetectorService.latestNetworkTime());
}
}
@Test
- public void testGetLatestNetworkSuggestion_noTimeAvailable() {
+ public void testLatestNetworkTime_noTimeAvailable() {
if (TimeDetectorNetworkTimeHelper.isInUse()) {
mFakeTimeDetectorStrategySpy.setLatestNetworkTime(null);
-
- assertNull(mTimeDetectorService.getLatestNetworkSuggestion());
} else {
when(mMockNtpTrustedTime.getCachedTimeResult()).thenReturn(null);
- assertNull(mTimeDetectorService.getLatestNetworkSuggestion());
}
+ assertThrows(ParcelableException.class, () -> mTimeDetectorService.latestNetworkTime());
}
@Test