Loading core/java/android/util/NtpTrustedTime.java +7 −0 Original line number Diff line number Diff line Loading @@ -265,6 +265,13 @@ public class NtpTrustedTime implements TrustedTime { return mTimeResult; } /** Clears the last received NTP. Intended for use during tests. */ public void clearCachedTimeResult() { synchronized (this) { mTimeResult = null; } } private static class NtpConnectionInfo { @NonNull private final String mServer; Loading services/core/java/com/android/server/NetworkTimeUpdateService.java +57 −6 Original line number Diff line number Diff line Loading @@ -36,12 +36,15 @@ import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.os.PowerManager; import android.os.ResultReceiver; import android.os.ShellCallback; import android.os.SystemClock; import android.os.TimestampedValue; import android.provider.Settings; import android.util.LocalLog; import android.util.Log; import android.util.NtpTrustedTime; import android.util.NtpTrustedTime.TimeResult; import android.util.TimeUtils; import com.android.internal.util.DumpUtils; Loading Loading @@ -152,6 +155,42 @@ public class NetworkTimeUpdateService extends Binder { }, 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) { // If we don't have any default network, don't bother. if (mDefaultNetwork == null) return; Loading Loading @@ -193,12 +232,8 @@ public class NetworkTimeUpdateService extends Binder { resetAlarm(mPollingIntervalMs - cachedNtpResult.getAgeMillis(currentElapsedRealtimeMillis)); // Suggest the time to the time detector. It may choose use it to set the system clock. TimestampedValue<Long> timeSignal = new TimestampedValue<>( cachedNtpResult.getElapsedRealtimeMillis(), cachedNtpResult.getTimeMillis()); NetworkTimeSuggestion timeSuggestion = new NetworkTimeSuggestion(timeSignal); timeSuggestion.addDebugInfo("Origin: NetworkTimeUpdateService. event=" + event); mTimeDetector.suggestNetworkTime(timeSuggestion); makeNetworkTimeSuggestion(cachedNtpResult, "Origin: NetworkTimeUpdateService. event=" + event); } else { // No fresh fix; schedule retry mTryAgainCounter++; Loading @@ -217,6 +252,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. * Loading Loading @@ -320,4 +364,11 @@ public class NetworkTimeUpdateService extends Binder { mLocalLog.dump(fd, pw, args); 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); } } services/core/java/com/android/server/NetworkTimeUpdateServiceShellCommand.java 0 → 100644 +90 −0 Original line number 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(); } } Loading
core/java/android/util/NtpTrustedTime.java +7 −0 Original line number Diff line number Diff line Loading @@ -265,6 +265,13 @@ public class NtpTrustedTime implements TrustedTime { return mTimeResult; } /** Clears the last received NTP. Intended for use during tests. */ public void clearCachedTimeResult() { synchronized (this) { mTimeResult = null; } } private static class NtpConnectionInfo { @NonNull private final String mServer; Loading
services/core/java/com/android/server/NetworkTimeUpdateService.java +57 −6 Original line number Diff line number Diff line Loading @@ -36,12 +36,15 @@ import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.os.PowerManager; import android.os.ResultReceiver; import android.os.ShellCallback; import android.os.SystemClock; import android.os.TimestampedValue; import android.provider.Settings; import android.util.LocalLog; import android.util.Log; import android.util.NtpTrustedTime; import android.util.NtpTrustedTime.TimeResult; import android.util.TimeUtils; import com.android.internal.util.DumpUtils; Loading Loading @@ -152,6 +155,42 @@ public class NetworkTimeUpdateService extends Binder { }, 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) { // If we don't have any default network, don't bother. if (mDefaultNetwork == null) return; Loading Loading @@ -193,12 +232,8 @@ public class NetworkTimeUpdateService extends Binder { resetAlarm(mPollingIntervalMs - cachedNtpResult.getAgeMillis(currentElapsedRealtimeMillis)); // Suggest the time to the time detector. It may choose use it to set the system clock. TimestampedValue<Long> timeSignal = new TimestampedValue<>( cachedNtpResult.getElapsedRealtimeMillis(), cachedNtpResult.getTimeMillis()); NetworkTimeSuggestion timeSuggestion = new NetworkTimeSuggestion(timeSignal); timeSuggestion.addDebugInfo("Origin: NetworkTimeUpdateService. event=" + event); mTimeDetector.suggestNetworkTime(timeSuggestion); makeNetworkTimeSuggestion(cachedNtpResult, "Origin: NetworkTimeUpdateService. event=" + event); } else { // No fresh fix; schedule retry mTryAgainCounter++; Loading @@ -217,6 +252,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. * Loading Loading @@ -320,4 +364,11 @@ public class NetworkTimeUpdateService extends Binder { mLocalLog.dump(fd, pw, args); 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); } }
services/core/java/com/android/server/NetworkTimeUpdateServiceShellCommand.java 0 → 100644 +90 −0 Original line number 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(); } }