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

Commit 5ef61031 authored by Neil Fuller's avatar Neil Fuller
Browse files

Add NtpTrustedTime.forceRefresh(Network)

Add NtpTrustedTime.forceRefresh(Network). If a component that uses
NtpTrustedTime is monitoring network connectivity, it should probably
provide the network to be used, otherwise there is a non-obvious
relationship between the network being monitored and the network
actually used.

Only one user of NtpTrustedTime is updated here as the other,
GnssLocationProvider / NtpTimeHelper, is going to be refactored in an
upcoming commit. Leaving it using the forceRefresh() method that doesn't
take a parameter is not a regression.

Bug: 222295093
Test: atest core/tests/coretests/src/android/util/NtpTrustedTimeTest
Test: Treehugger
Change-Id: I51db528d06359c33335c874aca524f5adee3f3a7
parent 9a0c9f23
Loading
Loading
Loading
Loading
+120 −90
Original line number Diff line number Diff line
@@ -44,7 +44,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Supplier;

/**
 * A singleton that connects with a remote NTP server as its trusted time source. This class
@@ -251,24 +250,47 @@ public abstract class NtpTrustedTime implements TrustedTime {
        }
    }

    /** Forces a refresh using the default network. */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public boolean forceRefresh() {
        synchronized (this) {
            NtpConfig ntpConfig = getNtpConfig();
            if (ntpConfig == null) {
                // missing server config, so no NTP time available
                if (LOGD) Log.d(TAG, "forceRefresh: invalid server config");
            Network network = getDefaultNetwork();
            if (network == null) {
                if (LOGD) Log.d(TAG, "forceRefresh: no network available");
                return false;
            }

            Network network = getNetwork();
            if (network == null) {
                if (LOGD) Log.d(TAG, "forceRefresh: no network available");
            return forceRefreshLocked(network);
        }
    }

    /** Forces a refresh using the specified network. */
    public boolean forceRefresh(@NonNull Network network) {
        Objects.requireNonNull(network);

        synchronized (this) {
            return forceRefreshLocked(network);
        }
    }

    @GuardedBy("this")
    private boolean forceRefreshLocked(@NonNull Network network) {
        Objects.requireNonNull(network);

        if (!isNetworkConnected(network)) {
            if (LOGD) Log.d(TAG, "forceRefreshLocked: network=" + network + " is not connected");
            return false;
        }

        NtpConfig ntpConfig = getNtpConfig();
        if (ntpConfig == null) {
            // missing server config, so no NTP time available
            if (LOGD) Log.d(TAG, "forceRefreshLocked: invalid server config");
            return false;
        }

        if (LOGD) {
                Log.d(TAG, "forceRefresh: NTP request network=" + network
            Log.d(TAG, "forceRefreshLocked: NTP request network=" + network
                    + " ntpConfig=" + ntpConfig);
        }

@@ -325,7 +347,6 @@ public abstract class NtpTrustedTime implements TrustedTime {
        }
        return false;
    }
    }

    @GuardedBy("this")
    private NtpConfig getNtpConfig() {
@@ -346,14 +367,23 @@ public abstract class NtpTrustedTime implements TrustedTime {
    public abstract NtpConfig getNtpConfigInternal();

    /**
     * Returns the {@link Network} to use during an NTP query. This method can return {@code null}
     * if there is no connectivity
     * Returns the default {@link Network} to use during an NTP query when no network is specified.
     * This method can return {@code null} if the device hasn't fully initialized or there is no
     * active network.
     *
     * <p>This method has been made public for easy replacement during tests.
     */
    @VisibleForTesting
    @Nullable
    public abstract Network getNetwork();
    public abstract Network getDefaultNetwork();

    /**
     * Returns {@code true} if there is likely to be connectivity on the supplied network.
     *
     * <p>This method has been made public for easy replacement during tests.
     */
    @VisibleForTesting
    public abstract boolean isNetworkConnected(@NonNull Network network);

    /**
     * Queries the specified NTP server. This is a blocking call. Returns {@code null} if the query
@@ -565,26 +595,9 @@ public abstract class NtpTrustedTime implements TrustedTime {
     */
    private static final class NtpTrustedTimeImpl extends NtpTrustedTime {

        /**
         * A supplier that returns the ConnectivityManager. The Supplier can return null if
         * ConnectivityService isn't running yet.
         */
        private final Supplier<ConnectivityManager> mConnectivityManagerSupplier =
                new Supplier<>() {
        @GuardedBy("this")
        private ConnectivityManager mConnectivityManager;

            @Nullable
            @Override
            public synchronized ConnectivityManager get() {
                // We can't do this at initialization time: ConnectivityService might not be running
                // yet.
                if (mConnectivityManager == null) {
                    mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
                }
                return mConnectivityManager;
            }
        };

        @NonNull
        private final Context mContext;

@@ -629,13 +642,20 @@ public abstract class NtpTrustedTime implements TrustedTime {
        }

        @Override
        public Network getNetwork() {
            ConnectivityManager connectivityManager = mConnectivityManagerSupplier.get();
        public Network getDefaultNetwork() {
            ConnectivityManager connectivityManager = getConnectivityManager();
            if (connectivityManager == null) {
                if (LOGD) Log.d(TAG, "getNetwork: no ConnectivityManager");
                return null;
            }
            final Network network = connectivityManager.getActiveNetwork();
            return connectivityManager.getActiveNetwork();
        }

        @Override
        public boolean isNetworkConnected(@NonNull Network network) {
            ConnectivityManager connectivityManager = getConnectivityManager();
            if (connectivityManager == null) {
                return false;
            }
            final NetworkInfo ni = connectivityManager.getNetworkInfo(network);

            // This connectivity check is to avoid performing a DNS lookup for the time server on a
@@ -649,9 +669,19 @@ public abstract class NtpTrustedTime implements TrustedTime {
            // addresses are actually reachable.
            if (ni == null || !ni.isConnected()) {
                if (LOGD) Log.d(TAG, "getNetwork: no connectivity");
                return null;
                return false;
            }
            return true;
        }
            return network;

        private synchronized ConnectivityManager getConnectivityManager() {
            if (mConnectivityManager == null) {
                mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
            }
            if (mConnectivityManager == null) {
                if (LOGD) Log.d(TAG, "getConnectivityManager: no ConnectivityManager");
            }
            return mConnectivityManager;
        }

        @Override