diff options
| author | 2011-07-10 16:18:58 -0700 | |
|---|---|---|
| committer | 2011-07-10 16:18:58 -0700 | |
| commit | ddafb64f94053aeafcaf6b6cb6073ed4cb56dacb (patch) | |
| tree | b4be693fddd05b9c7395bd2b00a9bb38d4ad2415 | |
| parent | 38715a8d861728446374f2bf0060c73fe1e3806d (diff) | |
| parent | 104344e507610be42fb70c7deda3c422c543bfcb (diff) | |
Merge "Cached NTP time for system services."
8 files changed, 98 insertions, 113 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 65babc2dea9b..23b53ae04ba4 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -3833,6 +3833,11 @@ public final class Settings { /** {@hide} */ public static final String NETSTATS_TAG_MAX_HISTORY = "netstats_tag_max_history"; + /** Preferred NTP server. {@hide} */ + public static final String NTP_SERVER = "ntp_server"; + /** Timeout in milliseconds to wait for NTP server. {@hide} */ + public static final String NTP_TIMEOUT = "ntp_timeout"; + /** * @hide */ diff --git a/core/java/android/util/NtpTrustedTime.java b/core/java/android/util/NtpTrustedTime.java index 5b19ecdb8b8a..2179ff36e1c7 100644 --- a/core/java/android/util/NtpTrustedTime.java +++ b/core/java/android/util/NtpTrustedTime.java @@ -16,41 +16,71 @@ package android.util; +import android.content.ContentResolver; +import android.content.Context; +import android.content.res.Resources; import android.net.SntpClient; import android.os.SystemClock; +import android.provider.Settings; /** - * {@link TrustedTime} that connects with a remote NTP server as its remote - * trusted time source. + * {@link TrustedTime} that connects with a remote NTP server as its trusted + * time source. * * @hide */ public class NtpTrustedTime implements TrustedTime { - private String mNtpServer; - private long mNtpTimeout; + private static final String TAG = "NtpTrustedTime"; + private static final boolean LOGD = false; + + private static NtpTrustedTime sSingleton; + + private final String mServer; + private final long mTimeout; private boolean mHasCache; private long mCachedNtpTime; private long mCachedNtpElapsedRealtime; private long mCachedNtpCertainty; - public NtpTrustedTime() { + private NtpTrustedTime(String server, long timeout) { + if (LOGD) Log.d(TAG, "creating NtpTrustedTime using " + server); + mServer = server; + mTimeout = timeout; } - public void setNtpServer(String server, long timeout) { - mNtpServer = server; - mNtpTimeout = timeout; + public static synchronized NtpTrustedTime getInstance(Context context) { + if (sSingleton == null) { + final Resources res = context.getResources(); + final ContentResolver resolver = context.getContentResolver(); + + final String defaultServer = res.getString( + com.android.internal.R.string.config_ntpServer); + final long defaultTimeout = res.getInteger( + com.android.internal.R.integer.config_ntpTimeout); + + final String secureServer = Settings.Secure.getString( + resolver, Settings.Secure.NTP_SERVER); + final long timeout = Settings.Secure.getLong( + resolver, Settings.Secure.NTP_TIMEOUT, defaultTimeout); + + final String server = secureServer != null ? secureServer : defaultServer; + sSingleton = new NtpTrustedTime(server, timeout); + } + + return sSingleton; } /** {@inheritDoc} */ public boolean forceRefresh() { - if (mNtpServer == null) { + if (mServer == null) { // missing server, so no trusted time available return false; } + if (LOGD) Log.d(TAG, "forceRefresh() from cache miss"); final SntpClient client = new SntpClient(); - if (client.requestTime(mNtpServer, (int) mNtpTimeout)) { + if (client.requestTime(mServer, (int) mTimeout)) { mHasCache = true; mCachedNtpTime = client.getNtpTime(); mCachedNtpElapsedRealtime = client.getNtpTimeReference(); @@ -89,9 +119,19 @@ public class NtpTrustedTime implements TrustedTime { if (!mHasCache) { throw new IllegalStateException("Missing authoritative time source"); } + if (LOGD) Log.d(TAG, "currentTimeMillis() cache hit"); // current time is age after the last ntp cache; callers who // want fresh values will hit makeAuthoritative() first. return mCachedNtpTime + getCacheAge(); } + + public long getCachedNtpTime() { + if (LOGD) Log.d(TAG, "getCachedNtpTime() cache hit"); + return mCachedNtpTime; + } + + public long getCachedNtpTimeReference() { + return mCachedNtpElapsedRealtime; + } } diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 9f05cbcba55c..1f2b7fbae95c 100755 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -660,4 +660,9 @@ extremely limited. --> <bool name="config_allowActionMenuItemTextWithIcon">false</bool> + <!-- Remote server that can provide NTP responses. --> + <string translatable="false" name="config_ntpServer">pool.ntp.org</string> + <!-- Timeout to wait for NTP server response. --> + <integer name="config_ntpTimeout">20000</integer> + </resources> diff --git a/services/java/com/android/server/NetworkTimeUpdateService.java b/services/java/com/android/server/NetworkTimeUpdateService.java index 15f22c0b2ad5..f7fe39ecfd68 100644 --- a/services/java/com/android/server/NetworkTimeUpdateService.java +++ b/services/java/com/android/server/NetworkTimeUpdateService.java @@ -16,8 +16,6 @@ package com.android.server; -import com.android.internal.telephony.TelephonyIntents; - import android.app.AlarmManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; @@ -28,7 +26,6 @@ import android.content.IntentFilter; import android.database.ContentObserver; import android.net.ConnectivityManager; import android.net.NetworkInfo; -import android.net.SntpClient; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; @@ -36,12 +33,10 @@ import android.os.Message; import android.os.SystemClock; import android.provider.Settings; import android.util.Log; -import android.util.Slog; +import android.util.NtpTrustedTime; +import android.util.TrustedTime; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.Properties; +import com.android.internal.telephony.TelephonyIntents; /** * Monitors the network time and updates the system time if it is out of sync @@ -68,14 +63,11 @@ public class NetworkTimeUpdateService { private static final long POLLING_INTERVAL_SHORTER_MS = 60 * 1000L; // 60 seconds /** Number of times to try again */ private static final int TRY_AGAIN_TIMES_MAX = 3; - /** How long to wait for the NTP server to respond. */ - private static final int MAX_NTP_FETCH_WAIT_MS = 20 * 1000; /** If the time difference is greater than this threshold, then update the time. */ private static final int TIME_ERROR_THRESHOLD_MS = 5 * 1000; private static final String ACTION_POLL = "com.android.server.NetworkTimeUpdateService.action.POLL"; - private static final String PROPERTIES_FILE = "/etc/gps.conf"; private static int POLL_REQUEST = 0; private static final long NOT_SET = -1; @@ -84,14 +76,14 @@ public class NetworkTimeUpdateService { private long mNitzZoneSetTime = NOT_SET; private Context mContext; + private TrustedTime mTime; + // NTP lookup is done on this thread and handler private Handler mHandler; private HandlerThread mThread; private AlarmManager mAlarmManager; private PendingIntent mPendingPollIntent; private SettingsObserver mSettingsObserver; - // Address of the NTP server - private String mNtpServer; // The last time that we successfully fetched the NTP time. private long mLastNtpFetchTime = NOT_SET; // Keeps track of how many quick attempts were made to fetch NTP time. @@ -101,6 +93,7 @@ public class NetworkTimeUpdateService { public NetworkTimeUpdateService(Context context) { mContext = context; + mTime = NtpTrustedTime.getInstance(context); mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); Intent pollIntent = new Intent(ACTION_POLL, null); mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0); @@ -108,12 +101,6 @@ public class NetworkTimeUpdateService { /** Initialize the receivers and initiate the first NTP request */ public void systemReady() { - mNtpServer = getNtpServerAddress(); - if (mNtpServer == null) { - Slog.e(TAG, "NTP server address not found, not syncing to NTP time"); - return; - } - registerForTelephonyIntents(); registerForAlarms(); registerForConnectivityIntents(); @@ -128,27 +115,6 @@ public class NetworkTimeUpdateService { mSettingsObserver.observe(mContext); } - private String getNtpServerAddress() { - String serverAddress = null; - FileInputStream stream = null; - try { - Properties properties = new Properties(); - File file = new File(PROPERTIES_FILE); - stream = new FileInputStream(file); - properties.load(stream); - serverAddress = properties.getProperty("NTP_SERVER", null); - } catch (IOException e) { - Slog.e(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE); - } finally { - if (stream != null) { - try { - stream.close(); - } catch (Exception e) {} - } - } - return serverAddress; - } - private void registerForTelephonyIntents() { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(TelephonyIntents.ACTION_NETWORK_SET_TIME); @@ -189,9 +155,15 @@ public class NetworkTimeUpdateService { if (mLastNtpFetchTime == NOT_SET || refTime >= mLastNtpFetchTime + POLLING_INTERVAL_MS || event == EVENT_AUTO_TIME_CHANGED) { if (DBG) Log.d(TAG, "Before Ntp fetch"); - long ntp = getNtpTime(); - if (DBG) Log.d(TAG, "Ntp = " + ntp); - if (ntp > 0) { + + // force refresh NTP cache when outdated + if (mTime.getCacheAge() >= POLLING_INTERVAL_MS) { + mTime.forceRefresh(); + } + + // only update when NTP time is fresh + if (mTime.getCacheAge() < POLLING_INTERVAL_MS) { + final long ntp = mTime.currentTimeMillis(); mTryAgainCounter = 0; mLastNtpFetchTime = SystemClock.elapsedRealtime(); if (Math.abs(ntp - currentTime) > TIME_ERROR_THRESHOLD_MS) { @@ -232,15 +204,6 @@ public class NetworkTimeUpdateService { mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, next, mPendingPollIntent); } - private long getNtpTime() { - SntpClient client = new SntpClient(); - if (client.requestTime(mNtpServer, MAX_NTP_FETCH_WAIT_MS)) { - return client.getNtpTime(); - } else { - return 0; - } - } - /** * Checks if the user prefers to automatically set the time. */ diff --git a/services/java/com/android/server/ThrottleService.java b/services/java/com/android/server/ThrottleService.java index d81dfdbc1b8d..24d4dd3451d0 100644 --- a/services/java/com/android/server/ThrottleService.java +++ b/services/java/com/android/server/ThrottleService.java @@ -16,9 +16,6 @@ package com.android.server; -import com.android.internal.R; -import com.android.internal.telephony.TelephonyProperties; - import android.app.AlarmManager; import android.app.Notification; import android.app.NotificationManager; @@ -54,6 +51,9 @@ import android.util.NtpTrustedTime; import android.util.Slog; import android.util.TrustedTime; +import com.android.internal.R; +import com.android.internal.telephony.TelephonyProperties; + import java.io.BufferedWriter; import java.io.File; import java.io.FileDescriptor; @@ -63,7 +63,6 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.Calendar; import java.util.GregorianCalendar; -import java.util.Properties; import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; @@ -87,7 +86,6 @@ public class ThrottleService extends IThrottleManager.Stub { private static final long TESTING_THRESHOLD = 1 * 1024 * 1024; private static final long MAX_NTP_CACHE_AGE = 24 * 60 * 60 * 1000; - private static final long MAX_NTP_FETCH_WAIT = 20 * 1000; private long mMaxNtpCacheAge = MAX_NTP_CACHE_AGE; @@ -127,8 +125,6 @@ public class ThrottleService extends IThrottleManager.Stub { private static final int THROTTLE_INDEX_UNINITIALIZED = -1; private static final int THROTTLE_INDEX_UNTHROTTLED = 0; - private static final String PROPERTIES_FILE = "/etc/gps.conf"; - private Intent mPollStickyBroadcast; private TrustedTime mTime; @@ -139,8 +135,7 @@ public class ThrottleService extends IThrottleManager.Stub { } public ThrottleService(Context context) { - // TODO: move to using cached NtpTrustedTime - this(context, getNetworkManagementService(), new NtpTrustedTime(), + this(context, getNetworkManagementService(), NtpTrustedTime.getInstance(context), context.getResources().getString(R.string.config_datause_iface)); } @@ -341,26 +336,6 @@ public class ThrottleService extends IThrottleManager.Stub { } }, new IntentFilter(ACTION_RESET)); - FileInputStream stream = null; - try { - Properties properties = new Properties(); - File file = new File(PROPERTIES_FILE); - stream = new FileInputStream(file); - properties.load(stream); - final String ntpServer = properties.getProperty("NTP_SERVER", null); - if (mTime instanceof NtpTrustedTime) { - ((NtpTrustedTime) mTime).setNtpServer(ntpServer, MAX_NTP_FETCH_WAIT); - } - } catch (IOException e) { - Slog.e(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE); - } finally { - if (stream != null) { - try { - stream.close(); - } catch (Exception e) {} - } - } - // use a new thread as we don't want to stall the system for file writes mThread = new HandlerThread(TAG); mThread.start(); diff --git a/services/java/com/android/server/location/GpsLocationProvider.java b/services/java/com/android/server/location/GpsLocationProvider.java index 4fa3bda0b13f..c813d3769ca8 100755 --- a/services/java/com/android/server/location/GpsLocationProvider.java +++ b/services/java/com/android/server/location/GpsLocationProvider.java @@ -32,7 +32,6 @@ import android.location.LocationManager; import android.location.LocationProvider; import android.net.ConnectivityManager; import android.net.NetworkInfo; -import android.net.SntpClient; import android.os.Binder; import android.os.Bundle; import android.os.Handler; @@ -51,6 +50,7 @@ import android.telephony.SmsMessage; import android.telephony.TelephonyManager; import android.telephony.gsm.GsmCellLocation; import android.util.Log; +import android.util.NtpTrustedTime; import android.util.SparseIntArray; import com.android.internal.app.IBatteryStats; @@ -61,7 +61,7 @@ import com.android.internal.telephony.Phone; import java.io.File; import java.io.FileInputStream; import java.io.IOException; -import java.io.StringBufferInputStream; +import java.io.StringReader; import java.util.ArrayList; import java.util.Date; import java.util.Map.Entry; @@ -235,13 +235,13 @@ public class GpsLocationProvider implements LocationProviderInterface { // properties loaded from PROPERTIES_FILE private Properties mProperties; - private String mNtpServer; private String mSuplServerHost; private int mSuplServerPort; private String mC2KServerHost; private int mC2KServerPort; private final Context mContext; + private final NtpTrustedTime mNtpTime; private final ILocationManager mLocationManager; private Location mLocation = new Location(LocationManager.GPS_PROVIDER); private Bundle mLocationExtras = new Bundle(); @@ -286,10 +286,6 @@ public class GpsLocationProvider implements LocationProviderInterface { // current setting - 5 minutes private static final long RETRY_INTERVAL = 5*60*1000; - // to avoid injecting bad NTP time, we reject any time fixes that differ from system time - // by more than 5 minutes. - private static final long MAX_NTP_SYSTEM_TIME_OFFSET = 5*60*1000; - private final IGpsStatusProvider mGpsStatusProvider = new IGpsStatusProvider.Stub() { public void addGpsStatusListener(IGpsStatusListener listener) throws RemoteException { if (listener == null) { @@ -378,6 +374,7 @@ public class GpsLocationProvider implements LocationProviderInterface { public GpsLocationProvider(Context context, ILocationManager locationManager) { mContext = context; + mNtpTime = NtpTrustedTime.getInstance(context); mLocationManager = locationManager; mNIHandler = new GpsNetInitiatedHandler(context); @@ -418,7 +415,6 @@ public class GpsLocationProvider implements LocationProviderInterface { FileInputStream stream = new FileInputStream(file); mProperties.load(stream); stream.close(); - mNtpServer = mProperties.getProperty("NTP_SERVER", null); mSuplServerHost = mProperties.getProperty("SUPL_HOST"); String portString = mProperties.getProperty("SUPL_PORT"); @@ -530,13 +526,18 @@ public class GpsLocationProvider implements LocationProviderInterface { } mInjectNtpTimePending = false; - SntpClient client = new SntpClient(); long delay; - if (client.requestTime(mNtpServer, 10000)) { - long time = client.getNtpTime(); - long timeReference = client.getNtpTimeReference(); - int certainty = (int)(client.getRoundTripTime()/2); + // force refresh NTP cache when outdated + if (mNtpTime.getCacheAge() >= NTP_INTERVAL) { + mNtpTime.forceRefresh(); + } + + // only update when NTP time is fresh + if (mNtpTime.getCacheAge() < NTP_INTERVAL) { + long time = mNtpTime.getCachedNtpTime(); + long timeReference = mNtpTime.getCachedNtpTimeReference(); + long certainty = mNtpTime.getCacheCertainty(); long now = System.currentTimeMillis(); Log.d(TAG, "NTP server returned: " @@ -545,7 +546,7 @@ public class GpsLocationProvider implements LocationProviderInterface { + " certainty: " + certainty + " system time offset: " + (time - now)); - native_inject_time(time, timeReference, certainty); + native_inject_time(time, timeReference, (int) certainty); delay = NTP_INTERVAL; } else { if (DEBUG) Log.d(TAG, "requestTime failed"); @@ -1395,7 +1396,7 @@ public class GpsLocationProvider implements LocationProviderInterface { Properties extraProp = new Properties(); try { - extraProp.load(new StringBufferInputStream(extras)); + extraProp.load(new StringReader(extras)); } catch (IOException e) { diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java index 2a17cbe7afda..d23d0f4564e4 100644 --- a/services/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java @@ -204,9 +204,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { public NetworkPolicyManagerService(Context context, IActivityManager activityManager, IPowerManager powerManager, INetworkStatsService networkStats, INetworkManagementService networkManagement) { - // TODO: move to using cached NtpTrustedTime this(context, activityManager, powerManager, networkStats, networkManagement, - new NtpTrustedTime(), getSystemDir()); + NtpTrustedTime.getInstance(context), getSystemDir()); } private static File getSystemDir() { diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java index b4bd17690605..b6834f66341c 100644 --- a/services/java/com/android/server/net/NetworkStatsService.java +++ b/services/java/com/android/server/net/NetworkStatsService.java @@ -27,7 +27,6 @@ import static android.net.NetworkStats.IFACE_ALL; import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.UID_ALL; import static android.net.TrafficStats.UID_REMOVED; -import static android.provider.Settings.Secure.NETSTATS_ENABLED; import static android.provider.Settings.Secure.NETSTATS_NETWORK_BUCKET_DURATION; import static android.provider.Settings.Secure.NETSTATS_NETWORK_MAX_HISTORY; import static android.provider.Settings.Secure.NETSTATS_PERSIST_THRESHOLD; @@ -71,7 +70,6 @@ import android.util.Slog; import android.util.TrustedTime; import com.android.internal.os.AtomicFile; -import com.android.server.NativeDaemonConnectorException; import com.google.android.collect.Maps; import com.google.android.collect.Sets; @@ -175,9 +173,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { public NetworkStatsService( Context context, INetworkManagementService networkManager, IAlarmManager alarmManager) { - // TODO: move to using cached NtpTrustedTime - this(context, networkManager, alarmManager, new NtpTrustedTime(), getSystemDir(), - new DefaultNetworkStatsSettings(context)); + this(context, networkManager, alarmManager, NtpTrustedTime.getInstance(context), + getSystemDir(), new DefaultNetworkStatsSettings(context)); } private static File getSystemDir() { |