Merge "Make NTP config configurable from cmd"
This commit is contained in:
@@ -33,6 +33,9 @@ import android.text.TextUtils;
|
|||||||
|
|
||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
@@ -96,8 +99,8 @@ public class NtpTrustedTime implements TrustedTime {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "TimeResult{"
|
return "TimeResult{"
|
||||||
+ "mTimeMillis=" + mTimeMillis
|
+ "mTimeMillis=" + Instant.ofEpochMilli(mTimeMillis)
|
||||||
+ ", mElapsedRealtimeMillis=" + mElapsedRealtimeMillis
|
+ ", mElapsedRealtimeMillis=" + Duration.ofMillis(mElapsedRealtimeMillis)
|
||||||
+ ", mCertaintyMillis=" + mCertaintyMillis
|
+ ", mCertaintyMillis=" + mCertaintyMillis
|
||||||
+ '}';
|
+ '}';
|
||||||
}
|
}
|
||||||
@@ -131,6 +134,14 @@ public class NtpTrustedTime implements TrustedTime {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** An in-memory config override for use during tests. */
|
||||||
|
@Nullable
|
||||||
|
private String mHostnameForTests;
|
||||||
|
|
||||||
|
/** An in-memory config override for use during tests. */
|
||||||
|
@Nullable
|
||||||
|
private Duration mTimeoutForTests;
|
||||||
|
|
||||||
// Declared volatile and accessed outside of synchronized blocks to avoid blocking reads during
|
// Declared volatile and accessed outside of synchronized blocks to avoid blocking reads during
|
||||||
// forceRefresh().
|
// forceRefresh().
|
||||||
private volatile TimeResult mTimeResult;
|
private volatile TimeResult mTimeResult;
|
||||||
@@ -148,12 +159,23 @@ public class NtpTrustedTime implements TrustedTime {
|
|||||||
return sSingleton;
|
return sSingleton;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the NTP server config for tests. Passing {@code null} to a parameter clears the
|
||||||
|
* test value, i.e. so the normal value will be used next time.
|
||||||
|
*/
|
||||||
|
public void setServerConfigForTests(@Nullable String hostname, @Nullable Duration timeout) {
|
||||||
|
synchronized (this) {
|
||||||
|
mHostnameForTests = hostname;
|
||||||
|
mTimeoutForTests = timeout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||||||
public boolean forceRefresh() {
|
public boolean forceRefresh() {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
NtpConnectionInfo connectionInfo = getNtpConnectionInfo();
|
NtpConnectionInfo connectionInfo = getNtpConnectionInfo();
|
||||||
if (connectionInfo == null) {
|
if (connectionInfo == null) {
|
||||||
// missing server config, so no trusted time available
|
// missing server config, so no NTP time available
|
||||||
if (LOGD) Log.d(TAG, "forceRefresh: invalid server config");
|
if (LOGD) Log.d(TAG, "forceRefresh: invalid server config");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -290,6 +312,14 @@ public class NtpTrustedTime implements TrustedTime {
|
|||||||
int getTimeoutMillis() {
|
int getTimeoutMillis() {
|
||||||
return mTimeoutMillis;
|
return mTimeoutMillis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "NtpConnectionInfo{"
|
||||||
|
+ "mServer='" + mServer + '\''
|
||||||
|
+ ", mTimeoutMillis=" + mTimeoutMillis
|
||||||
|
+ '}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
@@ -297,17 +327,41 @@ public class NtpTrustedTime implements TrustedTime {
|
|||||||
final ContentResolver resolver = mContext.getContentResolver();
|
final ContentResolver resolver = mContext.getContentResolver();
|
||||||
|
|
||||||
final Resources res = mContext.getResources();
|
final Resources res = mContext.getResources();
|
||||||
final String defaultServer = res.getString(
|
|
||||||
com.android.internal.R.string.config_ntpServer);
|
|
||||||
final int defaultTimeoutMillis = res.getInteger(
|
|
||||||
com.android.internal.R.integer.config_ntpTimeout);
|
|
||||||
|
|
||||||
final String secureServer = Settings.Global.getString(
|
final String hostname;
|
||||||
resolver, Settings.Global.NTP_SERVER);
|
if (mHostnameForTests != null) {
|
||||||
final int timeoutMillis = Settings.Global.getInt(
|
hostname = mHostnameForTests;
|
||||||
resolver, Settings.Global.NTP_TIMEOUT, defaultTimeoutMillis);
|
} else {
|
||||||
|
String serverGlobalSetting =
|
||||||
|
Settings.Global.getString(resolver, Settings.Global.NTP_SERVER);
|
||||||
|
if (serverGlobalSetting != null) {
|
||||||
|
hostname = serverGlobalSetting;
|
||||||
|
} else {
|
||||||
|
hostname = res.getString(com.android.internal.R.string.config_ntpServer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final String server = secureServer != null ? secureServer : defaultServer;
|
final int timeoutMillis;
|
||||||
return TextUtils.isEmpty(server) ? null : new NtpConnectionInfo(server, timeoutMillis);
|
if (mTimeoutForTests != null) {
|
||||||
|
timeoutMillis = (int) mTimeoutForTests.toMillis();
|
||||||
|
} else {
|
||||||
|
int defaultTimeoutMillis =
|
||||||
|
res.getInteger(com.android.internal.R.integer.config_ntpTimeout);
|
||||||
|
timeoutMillis = Settings.Global.getInt(
|
||||||
|
resolver, Settings.Global.NTP_TIMEOUT, defaultTimeoutMillis);
|
||||||
|
}
|
||||||
|
return TextUtils.isEmpty(hostname) ? null : new NtpConnectionInfo(hostname, timeoutMillis);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Prints debug information. */
|
||||||
|
public void dump(PrintWriter pw) {
|
||||||
|
synchronized (this) {
|
||||||
|
pw.println("getNtpConnectionInfo()=" + getNtpConnectionInfo());
|
||||||
|
pw.println("mTimeResult=" + mTimeResult);
|
||||||
|
if (mTimeResult != null) {
|
||||||
|
pw.println("mTimeResult.getAgeMillis()="
|
||||||
|
+ Duration.ofMillis(mTimeResult.getAgeMillis()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.android.server;
|
package com.android.server;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
import android.app.AlarmManager;
|
import android.app.AlarmManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.timedetector.NetworkTimeSuggestion;
|
import android.app.timedetector.NetworkTimeSuggestion;
|
||||||
@@ -45,12 +46,12 @@ import android.util.LocalLog;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.NtpTrustedTime;
|
import android.util.NtpTrustedTime;
|
||||||
import android.util.NtpTrustedTime.TimeResult;
|
import android.util.NtpTrustedTime.TimeResult;
|
||||||
import android.util.TimeUtils;
|
|
||||||
|
|
||||||
import com.android.internal.util.DumpUtils;
|
import com.android.internal.util.DumpUtils;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Monitors the network time. If looking up the network time fails for some reason, it tries a few
|
* Monitors the network time. If looking up the network time fails for some reason, it tries a few
|
||||||
@@ -191,6 +192,19 @@ public class NetworkTimeUpdateService extends Binder {
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the NTP server config for tests. Passing {@code null} to a parameter clears the
|
||||||
|
* test value, i.e. so the normal value will be used next time.
|
||||||
|
*/
|
||||||
|
void setServerConfigForTests(@Nullable String hostname, @Nullable Duration timeout) {
|
||||||
|
mContext.enforceCallingPermission(
|
||||||
|
android.Manifest.permission.SET_TIME, "set NTP server config for tests");
|
||||||
|
|
||||||
|
mLocalLog.log("Setting server config for tests: hostname=" + hostname
|
||||||
|
+ ", timeout=" + timeout);
|
||||||
|
mTime.setServerConfigForTests(hostname, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
private void onPollNetworkTime(int event) {
|
private void onPollNetworkTime(int event) {
|
||||||
// If we don't have any default network, don't bother.
|
// If we don't have any default network, don't bother.
|
||||||
if (mDefaultNetwork == null) return;
|
if (mDefaultNetwork == null) return;
|
||||||
@@ -349,17 +363,14 @@ public class NetworkTimeUpdateService extends Binder {
|
|||||||
@Override
|
@Override
|
||||||
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||||
if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
|
if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
|
||||||
pw.print("PollingIntervalMs: ");
|
pw.println("mPollingIntervalMs=" + Duration.ofMillis(mPollingIntervalMs));
|
||||||
TimeUtils.formatDuration(mPollingIntervalMs, pw);
|
pw.println("mPollingIntervalShorterMs=" + Duration.ofMillis(mPollingIntervalShorterMs));
|
||||||
pw.print("\nPollingIntervalShorterMs: ");
|
pw.println("mTryAgainTimesMax=" + mTryAgainTimesMax);
|
||||||
TimeUtils.formatDuration(mPollingIntervalShorterMs, pw);
|
pw.println("mTryAgainCounter=" + mTryAgainCounter);
|
||||||
pw.println("\nTryAgainTimesMax: " + mTryAgainTimesMax);
|
pw.println();
|
||||||
pw.println("\nTryAgainCounter: " + mTryAgainCounter);
|
pw.println("NtpTrustedTime:");
|
||||||
NtpTrustedTime.TimeResult ntpResult = mTime.getCachedTimeResult();
|
mTime.dump(pw);
|
||||||
pw.println("NTP cache result: " + ntpResult);
|
pw.println();
|
||||||
if (ntpResult != null) {
|
|
||||||
pw.println("NTP result age: " + ntpResult.getAgeMillis());
|
|
||||||
}
|
|
||||||
pw.println("Local logs:");
|
pw.println("Local logs:");
|
||||||
mLocalLog.dump(fd, pw, args);
|
mLocalLog.dump(fd, pw, args);
|
||||||
pw.println();
|
pw.println();
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
|
|||||||
import android.os.ShellCommand;
|
import android.os.ShellCommand;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/** Implements the shell command interface for {@link NetworkTimeUpdateService}. */
|
/** Implements the shell command interface for {@link NetworkTimeUpdateService}. */
|
||||||
@@ -40,6 +41,13 @@ class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
|
|||||||
*/
|
*/
|
||||||
private static final String SHELL_COMMAND_FORCE_REFRESH = "force_refresh";
|
private static final String SHELL_COMMAND_FORCE_REFRESH = "force_refresh";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A shell command that sets the NTP server config for tests. Config is cleared on reboot.
|
||||||
|
*/
|
||||||
|
private static final String SHELL_COMMAND_SET_SERVER_CONFIG = "set_server_config";
|
||||||
|
private static final String SET_SERVER_CONFIG_HOSTNAME_ARG = "--hostname";
|
||||||
|
private static final String SET_SERVER_CONFIG_TIMEOUT_ARG = "--timeout_millis";
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private final NetworkTimeUpdateService mNetworkTimeUpdateService;
|
private final NetworkTimeUpdateService mNetworkTimeUpdateService;
|
||||||
|
|
||||||
@@ -58,6 +66,8 @@ class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
|
|||||||
return runClearTime();
|
return runClearTime();
|
||||||
case SHELL_COMMAND_FORCE_REFRESH:
|
case SHELL_COMMAND_FORCE_REFRESH:
|
||||||
return runForceRefresh();
|
return runForceRefresh();
|
||||||
|
case SHELL_COMMAND_SET_SERVER_CONFIG:
|
||||||
|
return runSetServerConfig();
|
||||||
default: {
|
default: {
|
||||||
return handleDefaultCommands(cmd);
|
return handleDefaultCommands(cmd);
|
||||||
}
|
}
|
||||||
@@ -75,6 +85,29 @@ class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int runSetServerConfig() {
|
||||||
|
String hostname = null;
|
||||||
|
Duration timeout = null;
|
||||||
|
String opt;
|
||||||
|
while ((opt = getNextArg()) != null) {
|
||||||
|
switch (opt) {
|
||||||
|
case SET_SERVER_CONFIG_HOSTNAME_ARG: {
|
||||||
|
hostname = getNextArgRequired();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SET_SERVER_CONFIG_TIMEOUT_ARG: {
|
||||||
|
timeout = Duration.ofMillis(Integer.parseInt(getNextArgRequired()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
throw new IllegalArgumentException("Unknown option: " + opt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mNetworkTimeUpdateService.setServerConfigForTests(hostname, timeout);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onHelp() {
|
public void onHelp() {
|
||||||
final PrintWriter pw = getOutPrintWriter();
|
final PrintWriter pw = getOutPrintWriter();
|
||||||
@@ -85,6 +118,12 @@ class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
|
|||||||
pw.printf(" Clears the latest time.\n");
|
pw.printf(" Clears the latest time.\n");
|
||||||
pw.printf(" %s\n", SHELL_COMMAND_FORCE_REFRESH);
|
pw.printf(" %s\n", SHELL_COMMAND_FORCE_REFRESH);
|
||||||
pw.printf(" Refreshes the latest time. Prints whether it was successful.\n");
|
pw.printf(" Refreshes the latest time. Prints whether it was successful.\n");
|
||||||
|
pw.printf(" %s\n", SHELL_COMMAND_SET_SERVER_CONFIG);
|
||||||
|
pw.printf(" Sets the NTP server config for tests. The config is not persisted.\n");
|
||||||
|
pw.printf(" Options: [%s <hostname>] [%s <millis>]\n",
|
||||||
|
SET_SERVER_CONFIG_HOSTNAME_ARG, SET_SERVER_CONFIG_TIMEOUT_ARG);
|
||||||
|
pw.printf(" Each key/value is optional and must be specified to override the\n");
|
||||||
|
pw.printf(" normal value, not specifying a key causes it to reset to the original.\n");
|
||||||
pw.println();
|
pw.println();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user