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

Commit a6208228 authored by Neil Fuller's avatar Neil Fuller
Browse files

Make CTS tests ambivalent to server impl

Implement shell command test support that will work regardless of which
of the two location NetworkTimeHelper implementations is in use at the
time. This is to prevent CTS breaking if OEMs or form factors switch the
implementation to the new one during the next Android release cycle.

New shell commands have been added temporarily to support the new
SystemClockNetworkTimeTest and do the right thing depending on the
implementation in use. This avoids the need for the tests to know which
impl is in use. In a future release cycle, when the old impl is deleted
these shell commands can be removed and the test changed as the new impl
uses the time_detector and suitable commands (mostly) exist for other
reasons.

Bug: 222295093
Test: atest services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
Test: See associated CTS change
Change-Id: Icca02ec263bb20bc02a0dd6dd6cc13342d9e4e7b
parent fedd356d
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -114,6 +114,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}.
     *
+8 −1
Original line number Diff line number Diff line
@@ -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;
+0 −18
Original line number Diff line number Diff line
@@ -180,24 +180,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.
     *
+0 −14
Original line number Diff line number Diff line
@@ -36,11 +36,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.
     */
@@ -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);
+75 −21
Original line number Diff line number Diff line
@@ -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;
            }
        }
    }

    /**
@@ -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) {
Loading