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

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

Command-line interface: NetworkTimeUpdateService

Initial command-line interface for NetworkTimeUpdateService for use in
tests.

To be joined by more commands as they are identified.

Bug: 213393821
Test: adb shell cmd network_time_update_service help
Test: adb shell cmd network_time_update_service clear_time
      && adb shell dumpsys network_time_update_service
Test: adb shell cmd network_time_update_service force_refresh
      && adb shell dumpsys network_time_update_service
Change-Id: I033764a7df9759e9fd4da0b0776f6535a574ff59
parent 6bda795c
Loading
Loading
Loading
Loading
+7 −0
Original line number Original line Diff line number Diff line
@@ -265,6 +265,13 @@ public class NtpTrustedTime implements TrustedTime {
        return mTimeResult;
        return mTimeResult;
    }
    }


    /** Clears the last received NTP. Intended for use during tests. */
    public void clearCachedTimeResult() {
        synchronized (this) {
            mTimeResult = null;
        }
    }

    private static class NtpConnectionInfo {
    private static class NtpConnectionInfo {


        @NonNull private final String mServer;
        @NonNull private final String mServer;
+57 −6
Original line number Original line Diff line number Diff line
@@ -36,12 +36,15 @@ import android.os.HandlerThread;
import android.os.Looper;
import android.os.Looper;
import android.os.Message;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager;
import android.os.ResultReceiver;
import android.os.ShellCallback;
import android.os.SystemClock;
import android.os.SystemClock;
import android.os.TimestampedValue;
import android.os.TimestampedValue;
import android.provider.Settings;
import android.provider.Settings;
import android.util.LocalLog;
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.TimeUtils;
import android.util.TimeUtils;


import com.android.internal.util.DumpUtils;
import com.android.internal.util.DumpUtils;
@@ -152,6 +155,42 @@ public class NetworkTimeUpdateService extends Binder {
                }, new IntentFilter(ACTION_POLL));
                }, new IntentFilter(ACTION_POLL));
    }
    }


    /**
     * 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.
     */
    void clearTimeForTests() {
        mContext.enforceCallingPermission(
                android.Manifest.permission.SET_TIME, "clear latest network time");

        mTime.clearCachedTimeResult();

        mLocalLog.log("clearTimeForTests");
    }

    /**
     * Forces the service to refresh the NTP time.
     *
     * <p>This operation takes place in the calling thread rather than the service's handler thread.
     * This method does not affect currently scheduled refreshes. If the NTP request is successful
     * it will make an (asynchronously handled) suggestion to the time detector.
     */
    boolean forceRefreshForTests() {
        mContext.enforceCallingPermission(
                android.Manifest.permission.SET_TIME, "force network time refresh");

        boolean success = mTime.forceRefresh();
        mLocalLog.log("forceRefreshForTests: success=" + success);

        if (success) {
            makeNetworkTimeSuggestion(mTime.getCachedTimeResult(),
                    "Origin: NetworkTimeUpdateService: forceRefreshForTests");
        }

        return success;
    }

    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;
@@ -190,12 +229,8 @@ public class NetworkTimeUpdateService extends Binder {
            // Obtained fresh fix; schedule next normal update
            // Obtained fresh fix; schedule next normal update
            resetAlarm(mPollingIntervalMs);
            resetAlarm(mPollingIntervalMs);


            // Suggest the time to the time detector. It may choose use it to set the system clock.
            makeNetworkTimeSuggestion(cachedNtpResult,
            TimestampedValue<Long> timeSignal = new TimestampedValue<>(
                    "Origin: NetworkTimeUpdateService. event=" + event);
                    cachedNtpResult.getElapsedRealtimeMillis(), cachedNtpResult.getTimeMillis());
            NetworkTimeSuggestion timeSuggestion = new NetworkTimeSuggestion(timeSignal);
            timeSuggestion.addDebugInfo("Origin: NetworkTimeUpdateService. event=" + event);
            mTimeDetector.suggestNetworkTime(timeSuggestion);
        } else {
        } else {
            // No fresh fix; schedule retry
            // No fresh fix; schedule retry
            mTryAgainCounter++;
            mTryAgainCounter++;
@@ -214,6 +249,15 @@ public class NetworkTimeUpdateService extends Binder {
        }
        }
    }
    }


    /** Suggests the time to the time detector. It may choose use it to set the system clock. */
    private void makeNetworkTimeSuggestion(TimeResult ntpResult, String debugInfo) {
        TimestampedValue<Long> timeSignal = new TimestampedValue<>(
                ntpResult.getElapsedRealtimeMillis(), ntpResult.getTimeMillis());
        NetworkTimeSuggestion timeSuggestion = new NetworkTimeSuggestion(timeSignal);
        timeSuggestion.addDebugInfo(debugInfo);
        mTimeDetector.suggestNetworkTime(timeSuggestion);
    }

    /**
    /**
     * Cancel old alarm and starts a new one for the specified interval.
     * Cancel old alarm and starts a new one for the specified interval.
     *
     *
@@ -317,4 +361,11 @@ public class NetworkTimeUpdateService extends Binder {
        mLocalLog.dump(fd, pw, args);
        mLocalLog.dump(fd, pw, args);
        pw.println();
        pw.println();
    }
    }

    @Override
    public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
            String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
        new NetworkTimeUpdateServiceShellCommand(this).exec(
                this, in, out, err, args, callback, resultReceiver);
    }
}
}
+90 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2022 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 com.android.server;

import android.annotation.NonNull;
import android.os.ShellCommand;

import java.io.PrintWriter;
import java.util.Objects;

/** Implements the shell command interface for {@link NetworkTimeUpdateService}. */
class NetworkTimeUpdateServiceShellCommand extends ShellCommand {

    /**
     * The name of the service.
     */
    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";

    @NonNull
    private final NetworkTimeUpdateService mNetworkTimeUpdateService;

    NetworkTimeUpdateServiceShellCommand(NetworkTimeUpdateService networkTimeUpdateService) {
        mNetworkTimeUpdateService = Objects.requireNonNull(networkTimeUpdateService);
    }

    @Override
    public int onCommand(String cmd) {
        if (cmd == null) {
            return handleDefaultCommands(cmd);
        }

        switch (cmd) {
            case SHELL_COMMAND_CLEAR_TIME:
                return runClearTime();
            case SHELL_COMMAND_FORCE_REFRESH:
                return runForceRefresh();
            default: {
                return handleDefaultCommands(cmd);
            }
        }
    }

    private int runClearTime() {
        mNetworkTimeUpdateService.clearTimeForTests();
        return 0;
    }

    private int runForceRefresh() {
        boolean success = mNetworkTimeUpdateService.forceRefreshForTests();
        getOutPrintWriter().println(success);
        return 0;
    }

    @Override
    public void onHelp() {
        final PrintWriter pw = getOutPrintWriter();
        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.println();
    }
}