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

Commit 271dfbe8 authored by Neil Fuller's avatar Neil Fuller Committed by Gerrit Code Review
Browse files

Merge "Make NTP config configurable from cmd"

parents a29bc7bb 030a6921
Loading
Loading
Loading
Loading
+69 −15
Original line number Original line Diff line number Diff line
@@ -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 String hostname;
        final int defaultTimeoutMillis = res.getInteger(
        if (mHostnameForTests != null) {
                com.android.internal.R.integer.config_ntpTimeout);
            hostname = mHostnameForTests;

        } else {
        final String secureServer = Settings.Global.getString(
            String serverGlobalSetting =
                resolver, Settings.Global.NTP_SERVER);
                    Settings.Global.getString(resolver, Settings.Global.NTP_SERVER);
        final int timeoutMillis = Settings.Global.getInt(
            if (serverGlobalSetting != null) {
                hostname = serverGlobalSetting;
            } else {
                hostname = res.getString(com.android.internal.R.string.config_ntpServer);
            }
        }

        final int 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);
                    resolver, Settings.Global.NTP_TIMEOUT, defaultTimeoutMillis);
        }
        return TextUtils.isEmpty(hostname) ? null : new NtpConnectionInfo(hostname, timeoutMillis);
    }


        final String server = secureServer != null ? secureServer : defaultServer;
    /** Prints debug information. */
        return TextUtils.isEmpty(server) ? null : new NtpConnectionInfo(server, timeoutMillis);
    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()));
            }
        }
    }
    }
}
}
+23 −12
Original line number Original line Diff line number Diff line
@@ -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();
+39 −0
Original line number Original line Diff line number Diff line
@@ -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();
    }
    }
}
}