Merge "Watch network subtype, tethering teardown, empty."
This commit is contained in:
@@ -270,6 +270,11 @@ public class NetworkStatsHistory implements Parcelable {
|
||||
|| entry.operations < 0) {
|
||||
throw new IllegalArgumentException("tried recording negative data");
|
||||
}
|
||||
if (entry.rxBytes == 0 && entry.rxPackets == 0 && entry.txBytes == 0 && entry.txPackets == 0
|
||||
&& entry.operations == 0) {
|
||||
// nothing to record; skip
|
||||
return;
|
||||
}
|
||||
|
||||
// create any buckets needed by this range
|
||||
ensureBuckets(start, end);
|
||||
|
||||
@@ -35,6 +35,7 @@ import android.net.EthernetDataTracker;
|
||||
import android.net.IConnectivityManager;
|
||||
import android.net.INetworkPolicyListener;
|
||||
import android.net.INetworkPolicyManager;
|
||||
import android.net.INetworkStatsService;
|
||||
import android.net.LinkAddress;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.LinkProperties.CompareResult;
|
||||
@@ -306,8 +307,8 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
// the set of network types that can only be enabled by system/sig apps
|
||||
List mProtectedNetworks;
|
||||
|
||||
public ConnectivityService(
|
||||
Context context, INetworkManagementService netd, INetworkPolicyManager policyManager) {
|
||||
public ConnectivityService(Context context, INetworkManagementService netd,
|
||||
INetworkStatsService statsService, INetworkPolicyManager policyManager) {
|
||||
if (DBG) log("ConnectivityService starting up");
|
||||
|
||||
HandlerThread handlerThread = new HandlerThread("ConnectivityServiceThread");
|
||||
@@ -496,7 +497,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
|
||||
INetworkManagementService nmService = INetworkManagementService.Stub.asInterface(b);
|
||||
|
||||
mTethering = new Tethering(mContext, nmService, mHandler.getLooper());
|
||||
mTethering = new Tethering(mContext, nmService, statsService, mHandler.getLooper());
|
||||
mTetheringConfigValid = ((mTethering.getTetherableUsbRegexs().length != 0 ||
|
||||
mTethering.getTetherableWifiRegexs().length != 0 ||
|
||||
mTethering.getTetherableBluetoothRegexs().length != 0) &&
|
||||
|
||||
@@ -364,7 +364,8 @@ class ServerThread extends Thread {
|
||||
|
||||
try {
|
||||
Slog.i(TAG, "Connectivity Service");
|
||||
connectivity = new ConnectivityService(context, networkManagement, networkPolicy);
|
||||
connectivity = new ConnectivityService(
|
||||
context, networkManagement, networkStats, networkPolicy);
|
||||
ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
|
||||
networkStats.bindConnectivityManager(connectivity);
|
||||
networkPolicy.bindConnectivityManager(connectivity);
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.hardware.usb.UsbManager;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.IConnectivityManager;
|
||||
import android.net.INetworkManagementEventObserver;
|
||||
import android.net.INetworkStatsService;
|
||||
import android.net.InterfaceConfiguration;
|
||||
import android.net.LinkAddress;
|
||||
import android.net.LinkProperties;
|
||||
@@ -88,7 +89,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
|
||||
// upstream type list and the DUN_REQUIRED secure-setting
|
||||
private int mPreferredUpstreamMobileApn = ConnectivityManager.TYPE_NONE;
|
||||
|
||||
private INetworkManagementService mNMService;
|
||||
private final INetworkManagementService mNMService;
|
||||
private final INetworkStatsService mStatsService;
|
||||
private Looper mLooper;
|
||||
private HandlerThread mThread;
|
||||
|
||||
@@ -124,9 +126,11 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
|
||||
private boolean mUsbTetherRequested; // true if USB tethering should be started
|
||||
// when RNDIS is enabled
|
||||
|
||||
public Tethering(Context context, INetworkManagementService nmService, Looper looper) {
|
||||
public Tethering(Context context, INetworkManagementService nmService,
|
||||
INetworkStatsService statsService, Looper looper) {
|
||||
mContext = context;
|
||||
mNMService = nmService;
|
||||
mStatsService = statsService;
|
||||
mLooper = looper;
|
||||
|
||||
mIfaces = new HashMap<String, TetherInterfaceSM>();
|
||||
@@ -913,6 +917,9 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
|
||||
case CMD_INTERFACE_DOWN:
|
||||
if (mMyUpstreamIfaceName != null) {
|
||||
try {
|
||||
// about to tear down NAT; gather remaining statistics
|
||||
mStatsService.forceUpdate();
|
||||
|
||||
mNMService.disableNat(mIfaceName, mMyUpstreamIfaceName);
|
||||
mMyUpstreamIfaceName = null;
|
||||
} catch (Exception e) {
|
||||
@@ -957,6 +964,9 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
|
||||
}
|
||||
if (mMyUpstreamIfaceName != null) {
|
||||
try {
|
||||
// about to tear down NAT; gather remaining statistics
|
||||
mStatsService.forceUpdate();
|
||||
|
||||
mNMService.disableNat(mIfaceName, mMyUpstreamIfaceName);
|
||||
mMyUpstreamIfaceName = null;
|
||||
} catch (Exception e) {
|
||||
@@ -995,6 +1005,9 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
|
||||
case CMD_TETHER_MODE_DEAD:
|
||||
if (mMyUpstreamIfaceName != null) {
|
||||
try {
|
||||
// about to tear down NAT; gather remaining statistics
|
||||
mStatsService.forceUpdate();
|
||||
|
||||
mNMService.disableNat(mIfaceName, mMyUpstreamIfaceName);
|
||||
mMyUpstreamIfaceName = null;
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -24,8 +24,8 @@ import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
|
||||
import static android.content.Intent.ACTION_SHUTDOWN;
|
||||
import static android.content.Intent.ACTION_UID_REMOVED;
|
||||
import static android.content.Intent.EXTRA_UID;
|
||||
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
|
||||
import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
|
||||
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
|
||||
import static android.net.NetworkStats.IFACE_ALL;
|
||||
import static android.net.NetworkStats.SET_ALL;
|
||||
import static android.net.NetworkStats.SET_DEFAULT;
|
||||
@@ -43,9 +43,12 @@ import static android.provider.Settings.Secure.NETSTATS_POLL_INTERVAL;
|
||||
import static android.provider.Settings.Secure.NETSTATS_TAG_MAX_HISTORY;
|
||||
import static android.provider.Settings.Secure.NETSTATS_UID_BUCKET_DURATION;
|
||||
import static android.provider.Settings.Secure.NETSTATS_UID_MAX_HISTORY;
|
||||
import static android.telephony.PhoneStateListener.LISTEN_DATA_CONNECTION_STATE;
|
||||
import static android.telephony.PhoneStateListener.LISTEN_NONE;
|
||||
import static android.text.format.DateUtils.DAY_IN_MILLIS;
|
||||
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
|
||||
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
|
||||
import static android.text.format.DateUtils.SECOND_IN_MILLIS;
|
||||
import static com.android.internal.util.Preconditions.checkNotNull;
|
||||
import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
|
||||
import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
|
||||
@@ -80,6 +83,7 @@ import android.os.PowerManager;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.EventLog;
|
||||
import android.util.Log;
|
||||
@@ -121,7 +125,7 @@ import libcore.io.IoUtils;
|
||||
*/
|
||||
public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
private static final String TAG = "NetworkStats";
|
||||
private static final boolean LOGD = true;
|
||||
private static final boolean LOGD = false;
|
||||
private static final boolean LOGV = false;
|
||||
|
||||
/** File header magic number: "ANET" */
|
||||
@@ -132,7 +136,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
private static final int VERSION_UID_WITH_TAG = 3;
|
||||
private static final int VERSION_UID_WITH_SET = 4;
|
||||
|
||||
private static final int MSG_PERFORM_POLL = 0x1;
|
||||
private static final int MSG_PERFORM_POLL = 1;
|
||||
private static final int MSG_UPDATE_IFACES = 2;
|
||||
|
||||
/** Flags to control detail level of poll event. */
|
||||
private static final int FLAG_PERSIST_NETWORK = 0x10;
|
||||
@@ -144,6 +149,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
private final INetworkManagementService mNetworkManager;
|
||||
private final IAlarmManager mAlarmManager;
|
||||
private final TrustedTime mTime;
|
||||
private final TelephonyManager mTeleManager;
|
||||
private final NetworkStatsSettings mSettings;
|
||||
|
||||
private final PowerManager.WakeLock mWakeLock;
|
||||
@@ -227,6 +233,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
mNetworkManager = checkNotNull(networkManager, "missing INetworkManagementService");
|
||||
mAlarmManager = checkNotNull(alarmManager, "missing IAlarmManager");
|
||||
mTime = checkNotNull(time, "missing TrustedTime");
|
||||
mTeleManager = checkNotNull(TelephonyManager.getDefault(), "missing TelephonyManager");
|
||||
mSettings = checkNotNull(settings, "missing NetworkStatsSettings");
|
||||
|
||||
final PowerManager powerManager = (PowerManager) context.getSystemService(
|
||||
@@ -279,6 +286,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
// ignored; service lives in system_server
|
||||
}
|
||||
|
||||
// watch for networkType changes that aren't broadcast through
|
||||
// CONNECTIVITY_ACTION_IMMEDIATE above.
|
||||
mTeleManager.listen(mPhoneListener, LISTEN_DATA_CONNECTION_STATE);
|
||||
|
||||
registerPollAlarmLocked();
|
||||
registerGlobalAlert();
|
||||
|
||||
@@ -288,10 +299,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
|
||||
private void shutdownLocked() {
|
||||
mContext.unregisterReceiver(mConnReceiver);
|
||||
mContext.unregisterReceiver(mTetherReceiver);
|
||||
mContext.unregisterReceiver(mPollReceiver);
|
||||
mContext.unregisterReceiver(mRemovedReceiver);
|
||||
mContext.unregisterReceiver(mShutdownReceiver);
|
||||
|
||||
mTeleManager.listen(mPhoneListener, LISTEN_NONE);
|
||||
|
||||
writeNetworkStatsLocked();
|
||||
if (mUidStatsLoaded) {
|
||||
writeUidStatsLocked();
|
||||
@@ -535,14 +549,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
// on background handler thread, and verified CONNECTIVITY_INTERNAL
|
||||
// permission above.
|
||||
synchronized (mStatsLock) {
|
||||
mWakeLock.acquire();
|
||||
try {
|
||||
updateIfacesLocked();
|
||||
} finally {
|
||||
mWakeLock.release();
|
||||
}
|
||||
}
|
||||
updateIfaces();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -619,6 +626,46 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
}
|
||||
};
|
||||
|
||||
private int mLastPhoneState = TelephonyManager.DATA_UNKNOWN;
|
||||
private int mLastPhoneNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
|
||||
|
||||
/**
|
||||
* Receiver that watches for {@link TelephonyManager} changes, such as
|
||||
* transitioning between network types.
|
||||
*/
|
||||
private PhoneStateListener mPhoneListener = new PhoneStateListener() {
|
||||
@Override
|
||||
public void onDataConnectionStateChanged(int state, int networkType) {
|
||||
final boolean stateChanged = state != mLastPhoneState;
|
||||
final boolean networkTypeChanged = networkType != mLastPhoneNetworkType;
|
||||
|
||||
if (networkTypeChanged && !stateChanged) {
|
||||
// networkType changed without a state change, which means we
|
||||
// need to roll our own update. delay long enough for
|
||||
// ConnectivityManager to process.
|
||||
// TODO: add direct event to ConnectivityService instead of
|
||||
// relying on this delay.
|
||||
if (LOGV) Slog.v(TAG, "triggering delayed updateIfaces()");
|
||||
mHandler.sendMessageDelayed(
|
||||
mHandler.obtainMessage(MSG_UPDATE_IFACES), SECOND_IN_MILLIS);
|
||||
}
|
||||
|
||||
mLastPhoneState = state;
|
||||
mLastPhoneNetworkType = networkType;
|
||||
}
|
||||
};
|
||||
|
||||
private void updateIfaces() {
|
||||
synchronized (mStatsLock) {
|
||||
mWakeLock.acquire();
|
||||
try {
|
||||
updateIfacesLocked();
|
||||
} finally {
|
||||
mWakeLock.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inspect all current {@link NetworkState} to derive mapping from {@code
|
||||
* iface} to {@link NetworkStatsHistory}. When multiple {@link NetworkInfo}
|
||||
@@ -713,19 +760,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
final long threshold = mSettings.getPersistThreshold();
|
||||
|
||||
try {
|
||||
// record network stats
|
||||
final NetworkStats networkSnapshot = mNetworkManager.getNetworkStatsSummary();
|
||||
performNetworkPollLocked(networkSnapshot, currentTime);
|
||||
|
||||
// persist when enough network data has occurred
|
||||
final NetworkStats persistNetworkDelta = computeStatsDelta(
|
||||
mLastPersistNetworkSnapshot, networkSnapshot, true);
|
||||
final boolean networkPastThreshold = persistNetworkDelta.getTotalBytes() > threshold;
|
||||
if (persistForce || (persistNetwork && networkPastThreshold)) {
|
||||
writeNetworkStatsLocked();
|
||||
mLastPersistNetworkSnapshot = networkSnapshot;
|
||||
}
|
||||
|
||||
// record tethering stats; persisted during normal UID cycle below
|
||||
final String[] ifacePairs = mConnManager.getTetheredIfacePairs();
|
||||
final NetworkStats tetherSnapshot = mNetworkManager.getNetworkStatsTethering(
|
||||
@@ -744,6 +778,19 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
writeUidStatsLocked();
|
||||
mLastPersistUidSnapshot = uidSnapshot;
|
||||
}
|
||||
|
||||
// record network stats
|
||||
final NetworkStats networkSnapshot = mNetworkManager.getNetworkStatsSummary();
|
||||
performNetworkPollLocked(networkSnapshot, currentTime);
|
||||
|
||||
// persist when enough network data has occurred
|
||||
final NetworkStats persistNetworkDelta = computeStatsDelta(
|
||||
mLastPersistNetworkSnapshot, networkSnapshot, true);
|
||||
final boolean networkPastThreshold = persistNetworkDelta.getTotalBytes() > threshold;
|
||||
if (persistForce || (persistNetwork && networkPastThreshold)) {
|
||||
writeNetworkStatsLocked();
|
||||
mLastPersistNetworkSnapshot = networkSnapshot;
|
||||
}
|
||||
} catch (IllegalStateException e) {
|
||||
Log.wtf(TAG, "problem reading network stats", e);
|
||||
} catch (RemoteException e) {
|
||||
@@ -1356,6 +1403,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
performPoll(flags);
|
||||
return true;
|
||||
}
|
||||
case MSG_UPDATE_IFACES: {
|
||||
updateIfaces();
|
||||
return true;
|
||||
}
|
||||
default: {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -776,6 +776,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
|
||||
private void expectNetworkStatsPoll() throws Exception {
|
||||
mNetManager.setGlobalAlert(anyLong());
|
||||
expectLastCall().anyTimes();
|
||||
expect(mConnManager.getTetheredIfacePairs()).andReturn(null).anyTimes();
|
||||
}
|
||||
|
||||
private void assertStatsFilesExist(boolean exist) {
|
||||
|
||||
Reference in New Issue
Block a user