Better handling of NTP-based clocks.
Now that we have a nice Clock abstraction, we can use it to represent a clock backed by an NTP fix. (This makes testing logic much easier to write.) We now rely completely on NetworkTimeUpdateService to keep our NTP fix up to date, instead of trying to refresh in the middle of critical paths which could trigger random ANRs. Add internal FallbackClock to make it easier to handle missing NTP fixes. Add internal SimpleClock to let implementers focus on single millis() method. Test: bit FrameworksNetTests:com.android.server.net.NetworkStatsServiceTest Test: bit FrameworksServicesTests:com.android.server.NetworkPolicyManagerServiceTest Bug: 69714690, 72320957 Change-Id: Ic32cdcbe093d08b73b0e4b23d6910b23ea8e1968 Exempt-From-Owner-Approval: approved in previous PS
This commit is contained in:
committed by
Jeff Sharkey
parent
5e58ea8a2f
commit
77bd2dfb9f
@@ -68,6 +68,7 @@ import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
|
|||||||
import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
|
import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
|
||||||
import static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet;
|
import static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
import android.app.AlarmManager;
|
import android.app.AlarmManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.usage.NetworkStatsManager;
|
import android.app.usage.NetworkStatsManager;
|
||||||
@@ -97,6 +98,7 @@ import android.net.TrafficStats;
|
|||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.DropBoxManager;
|
import android.os.DropBoxManager;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
|
import android.os.BestClock;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
@@ -120,10 +122,8 @@ import android.util.ArraySet;
|
|||||||
import android.util.EventLog;
|
import android.util.EventLog;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.MathUtils;
|
import android.util.MathUtils;
|
||||||
import android.util.NtpTrustedTime;
|
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.SparseIntArray;
|
import android.util.SparseIntArray;
|
||||||
import android.util.TrustedTime;
|
|
||||||
import android.util.proto.ProtoOutputStream;
|
import android.util.proto.ProtoOutputStream;
|
||||||
|
|
||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
@@ -140,6 +140,8 @@ import java.io.File;
|
|||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.time.Clock;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -167,7 +169,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final INetworkManagementService mNetworkManager;
|
private final INetworkManagementService mNetworkManager;
|
||||||
private final AlarmManager mAlarmManager;
|
private final AlarmManager mAlarmManager;
|
||||||
private final TrustedTime mTime;
|
private final Clock mClock;
|
||||||
private final TelephonyManager mTeleManager;
|
private final TelephonyManager mTeleManager;
|
||||||
private final NetworkStatsSettings mSettings;
|
private final NetworkStatsSettings mSettings;
|
||||||
private final NetworkStatsObservers mStatsObservers;
|
private final NetworkStatsObservers mStatsObservers;
|
||||||
@@ -202,7 +204,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
*/
|
*/
|
||||||
public interface NetworkStatsSettings {
|
public interface NetworkStatsSettings {
|
||||||
public long getPollInterval();
|
public long getPollInterval();
|
||||||
public long getTimeCacheMaxAge();
|
|
||||||
public boolean getSampleEnabled();
|
public boolean getSampleEnabled();
|
||||||
public boolean getAugmentEnabled();
|
public boolean getAugmentEnabled();
|
||||||
|
|
||||||
@@ -281,16 +282,21 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
private long mPersistThreshold = 2 * MB_IN_BYTES;
|
private long mPersistThreshold = 2 * MB_IN_BYTES;
|
||||||
private long mGlobalAlertBytes;
|
private long mGlobalAlertBytes;
|
||||||
|
|
||||||
private static File getDefaultSystemDir() {
|
private static @NonNull File getDefaultSystemDir() {
|
||||||
return new File(Environment.getDataDirectory(), "system");
|
return new File(Environment.getDataDirectory(), "system");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static File getDefaultBaseDir() {
|
private static @NonNull File getDefaultBaseDir() {
|
||||||
File baseDir = new File(getDefaultSystemDir(), "netstats");
|
File baseDir = new File(getDefaultSystemDir(), "netstats");
|
||||||
baseDir.mkdirs();
|
baseDir.mkdirs();
|
||||||
return baseDir;
|
return baseDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static @NonNull Clock getDefaultClock() {
|
||||||
|
return new BestClock(ZoneOffset.UTC, SystemClock.currentNetworkTimeClock(),
|
||||||
|
Clock.systemUTC());
|
||||||
|
}
|
||||||
|
|
||||||
public static NetworkStatsService create(Context context,
|
public static NetworkStatsService create(Context context,
|
||||||
INetworkManagementService networkManager) {
|
INetworkManagementService networkManager) {
|
||||||
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||||
@@ -299,7 +305,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
|
powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
|
||||||
|
|
||||||
NetworkStatsService service = new NetworkStatsService(context, networkManager, alarmManager,
|
NetworkStatsService service = new NetworkStatsService(context, networkManager, alarmManager,
|
||||||
wakeLock, NtpTrustedTime.getInstance(context), TelephonyManager.getDefault(),
|
wakeLock, getDefaultClock(), TelephonyManager.getDefault(),
|
||||||
new DefaultNetworkStatsSettings(context), new NetworkStatsObservers(),
|
new DefaultNetworkStatsSettings(context), new NetworkStatsObservers(),
|
||||||
getDefaultSystemDir(), getDefaultBaseDir());
|
getDefaultSystemDir(), getDefaultBaseDir());
|
||||||
|
|
||||||
@@ -313,13 +319,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
NetworkStatsService(Context context, INetworkManagementService networkManager,
|
NetworkStatsService(Context context, INetworkManagementService networkManager,
|
||||||
AlarmManager alarmManager, PowerManager.WakeLock wakeLock, TrustedTime time,
|
AlarmManager alarmManager, PowerManager.WakeLock wakeLock, Clock clock,
|
||||||
TelephonyManager teleManager, NetworkStatsSettings settings,
|
TelephonyManager teleManager, NetworkStatsSettings settings,
|
||||||
NetworkStatsObservers statsObservers, File systemDir, File baseDir) {
|
NetworkStatsObservers statsObservers, File systemDir, File baseDir) {
|
||||||
mContext = checkNotNull(context, "missing Context");
|
mContext = checkNotNull(context, "missing Context");
|
||||||
mNetworkManager = checkNotNull(networkManager, "missing INetworkManagementService");
|
mNetworkManager = checkNotNull(networkManager, "missing INetworkManagementService");
|
||||||
mAlarmManager = checkNotNull(alarmManager, "missing AlarmManager");
|
mAlarmManager = checkNotNull(alarmManager, "missing AlarmManager");
|
||||||
mTime = checkNotNull(time, "missing TrustedTime");
|
mClock = checkNotNull(clock, "missing Clock");
|
||||||
mSettings = checkNotNull(settings, "missing NetworkStatsSettings");
|
mSettings = checkNotNull(settings, "missing NetworkStatsSettings");
|
||||||
mTeleManager = checkNotNull(teleManager, "missing TelephonyManager");
|
mTeleManager = checkNotNull(teleManager, "missing TelephonyManager");
|
||||||
mWakeLock = checkNotNull(wakeLock, "missing WakeLock");
|
mWakeLock = checkNotNull(wakeLock, "missing WakeLock");
|
||||||
@@ -413,8 +419,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
mContext.unregisterReceiver(mUserReceiver);
|
mContext.unregisterReceiver(mUserReceiver);
|
||||||
mContext.unregisterReceiver(mShutdownReceiver);
|
mContext.unregisterReceiver(mShutdownReceiver);
|
||||||
|
|
||||||
final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
|
final long currentTime = mClock.millis();
|
||||||
: System.currentTimeMillis();
|
|
||||||
|
|
||||||
// persist any pending stats
|
// persist any pending stats
|
||||||
mDevRecorder.forcePersistLocked(currentTime);
|
mDevRecorder.forcePersistLocked(currentTime);
|
||||||
@@ -831,8 +836,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update and persist if beyond new thresholds
|
// update and persist if beyond new thresholds
|
||||||
final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
|
final long currentTime = mClock.millis();
|
||||||
: System.currentTimeMillis();
|
|
||||||
synchronized (mStatsLock) {
|
synchronized (mStatsLock) {
|
||||||
if (!mSystemReady) return;
|
if (!mSystemReady) return;
|
||||||
|
|
||||||
@@ -1170,8 +1174,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
*/
|
*/
|
||||||
@GuardedBy("mStatsLock")
|
@GuardedBy("mStatsLock")
|
||||||
private void bootstrapStatsLocked() {
|
private void bootstrapStatsLocked() {
|
||||||
final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
|
final long currentTime = mClock.millis();
|
||||||
: System.currentTimeMillis();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
recordSnapshotLocked(currentTime);
|
recordSnapshotLocked(currentTime);
|
||||||
@@ -1183,11 +1186,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performPoll(int flags) {
|
private void performPoll(int flags) {
|
||||||
// try refreshing time source when stale
|
|
||||||
if (mTime.getCacheAge() > mSettings.getTimeCacheMaxAge()) {
|
|
||||||
mTime.forceRefresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (mStatsLock) {
|
synchronized (mStatsLock) {
|
||||||
mWakeLock.acquire();
|
mWakeLock.acquire();
|
||||||
|
|
||||||
@@ -1215,8 +1213,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
|
final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
|
||||||
|
|
||||||
// TODO: consider marking "untrusted" times in historical stats
|
// TODO: consider marking "untrusted" times in historical stats
|
||||||
final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
|
final long currentTime = mClock.millis();
|
||||||
: System.currentTimeMillis();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
recordSnapshotLocked(currentTime);
|
recordSnapshotLocked(currentTime);
|
||||||
@@ -1268,7 +1265,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
@GuardedBy("mStatsLock")
|
@GuardedBy("mStatsLock")
|
||||||
private void performSampleLocked() {
|
private void performSampleLocked() {
|
||||||
// TODO: migrate trustedtime fixes to separate binary log events
|
// TODO: migrate trustedtime fixes to separate binary log events
|
||||||
final long trustedTime = mTime.hasCache() ? mTime.currentTimeMillis() : -1;
|
final long currentTime = mClock.millis();
|
||||||
|
|
||||||
NetworkTemplate template;
|
NetworkTemplate template;
|
||||||
NetworkStats.Entry devTotal;
|
NetworkStats.Entry devTotal;
|
||||||
@@ -1285,7 +1282,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
|
devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
|
||||||
xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
|
xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
|
||||||
uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
|
uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
|
||||||
trustedTime);
|
currentTime);
|
||||||
|
|
||||||
// collect wifi sample
|
// collect wifi sample
|
||||||
template = buildTemplateWifiWildcard();
|
template = buildTemplateWifiWildcard();
|
||||||
@@ -1297,7 +1294,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
|
devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
|
||||||
xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
|
xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
|
||||||
uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
|
uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
|
||||||
trustedTime);
|
currentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1621,10 +1618,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
return getGlobalLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS);
|
return getGlobalLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public long getTimeCacheMaxAge() {
|
|
||||||
return getGlobalLong(NETSTATS_TIME_CACHE_MAX_AGE, DAY_IN_MILLIS);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public long getGlobalAlertBytes(long def) {
|
public long getGlobalAlertBytes(long def) {
|
||||||
return getGlobalLong(NETSTATS_GLOBAL_ALERT_BYTES, def);
|
return getGlobalLong(NETSTATS_GLOBAL_ALERT_BYTES, def);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user