Merge "Cached NTP time for system services."
This commit is contained in:
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user