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

Commit 9932a018 authored by Neil Fuller's avatar Neil Fuller Committed by Automerger Merge Worker
Browse files

Merge "Command-line interface: NetworkTimeUpdateService" am: 8ac370e6 am:...

Merge "Command-line interface: NetworkTimeUpdateService" am: 8ac370e6 am: 7b559562 am: f12a7839 am: 624a8921

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2002571

Change-Id: I1751aeb779bbf60f58909efa5e7ab4c359202bff
parents 02dada3a 624a8921
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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;
+57 −6
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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++;
@@ -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.
     *
@@ -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);
    }
}
+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();
    }
}