Skip to content

Commit 61c0818

Browse files
jsharkeyAndroid (Google) Code Review
authored andcommitted
Merge "Watch network subtype, tethering teardown, empty."
2 parents 83131db + 367d15a commit 61c0818

File tree

6 files changed

+102
-30
lines changed

6 files changed

+102
-30
lines changed

core/java/android/net/NetworkStatsHistory.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,11 @@ public void recordData(long start, long end, NetworkStats.Entry entry) {
270270
|| entry.operations < 0) {
271271
throw new IllegalArgumentException("tried recording negative data");
272272
}
273+
if (entry.rxBytes == 0 && entry.rxPackets == 0 && entry.txBytes == 0 && entry.txPackets == 0
274+
&& entry.operations == 0) {
275+
// nothing to record; skip
276+
return;
277+
}
273278

274279
// create any buckets needed by this range
275280
ensureBuckets(start, end);

services/java/com/android/server/ConnectivityService.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import android.net.IConnectivityManager;
3636
import android.net.INetworkPolicyListener;
3737
import android.net.INetworkPolicyManager;
38+
import android.net.INetworkStatsService;
3839
import android.net.LinkAddress;
3940
import android.net.LinkProperties;
4041
import android.net.LinkProperties.CompareResult;
@@ -306,8 +307,8 @@ public RadioAttributes(String init) {
306307
// the set of network types that can only be enabled by system/sig apps
307308
List mProtectedNetworks;
308309

309-
public ConnectivityService(
310-
Context context, INetworkManagementService netd, INetworkPolicyManager policyManager) {
310+
public ConnectivityService(Context context, INetworkManagementService netd,
311+
INetworkStatsService statsService, INetworkPolicyManager policyManager) {
311312
if (DBG) log("ConnectivityService starting up");
312313

313314
HandlerThread handlerThread = new HandlerThread("ConnectivityServiceThread");
@@ -496,7 +497,7 @@ public ConnectivityService(
496497
IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
497498
INetworkManagementService nmService = INetworkManagementService.Stub.asInterface(b);
498499

499-
mTethering = new Tethering(mContext, nmService, mHandler.getLooper());
500+
mTethering = new Tethering(mContext, nmService, statsService, mHandler.getLooper());
500501
mTetheringConfigValid = ((mTethering.getTetherableUsbRegexs().length != 0 ||
501502
mTethering.getTetherableWifiRegexs().length != 0 ||
502503
mTethering.getTetherableBluetoothRegexs().length != 0) &&

services/java/com/android/server/SystemServer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,8 @@ public void run() {
364364

365365
try {
366366
Slog.i(TAG, "Connectivity Service");
367-
connectivity = new ConnectivityService(context, networkManagement, networkPolicy);
367+
connectivity = new ConnectivityService(
368+
context, networkManagement, networkStats, networkPolicy);
368369
ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
369370
networkStats.bindConnectivityManager(connectivity);
370371
networkPolicy.bindConnectivityManager(connectivity);

services/java/com/android/server/connectivity/Tethering.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import android.net.ConnectivityManager;
3030
import android.net.IConnectivityManager;
3131
import android.net.INetworkManagementEventObserver;
32+
import android.net.INetworkStatsService;
3233
import android.net.InterfaceConfiguration;
3334
import android.net.LinkAddress;
3435
import android.net.LinkProperties;
@@ -88,7 +89,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
8889
// upstream type list and the DUN_REQUIRED secure-setting
8990
private int mPreferredUpstreamMobileApn = ConnectivityManager.TYPE_NONE;
9091

91-
private INetworkManagementService mNMService;
92+
private final INetworkManagementService mNMService;
93+
private final INetworkStatsService mStatsService;
9294
private Looper mLooper;
9395
private HandlerThread mThread;
9496

@@ -124,9 +126,11 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
124126
private boolean mUsbTetherRequested; // true if USB tethering should be started
125127
// when RNDIS is enabled
126128

127-
public Tethering(Context context, INetworkManagementService nmService, Looper looper) {
129+
public Tethering(Context context, INetworkManagementService nmService,
130+
INetworkStatsService statsService, Looper looper) {
128131
mContext = context;
129132
mNMService = nmService;
133+
mStatsService = statsService;
130134
mLooper = looper;
131135

132136
mIfaces = new HashMap<String, TetherInterfaceSM>();
@@ -913,6 +917,9 @@ public boolean processMessage(Message message) {
913917
case CMD_INTERFACE_DOWN:
914918
if (mMyUpstreamIfaceName != null) {
915919
try {
920+
// about to tear down NAT; gather remaining statistics
921+
mStatsService.forceUpdate();
922+
916923
mNMService.disableNat(mIfaceName, mMyUpstreamIfaceName);
917924
mMyUpstreamIfaceName = null;
918925
} catch (Exception e) {
@@ -957,6 +964,9 @@ public boolean processMessage(Message message) {
957964
}
958965
if (mMyUpstreamIfaceName != null) {
959966
try {
967+
// about to tear down NAT; gather remaining statistics
968+
mStatsService.forceUpdate();
969+
960970
mNMService.disableNat(mIfaceName, mMyUpstreamIfaceName);
961971
mMyUpstreamIfaceName = null;
962972
} catch (Exception e) {
@@ -995,6 +1005,9 @@ public boolean processMessage(Message message) {
9951005
case CMD_TETHER_MODE_DEAD:
9961006
if (mMyUpstreamIfaceName != null) {
9971007
try {
1008+
// about to tear down NAT; gather remaining statistics
1009+
mStatsService.forceUpdate();
1010+
9981011
mNMService.disableNat(mIfaceName, mMyUpstreamIfaceName);
9991012
mMyUpstreamIfaceName = null;
10001013
} catch (Exception e) {

services/java/com/android/server/net/NetworkStatsService.java

Lines changed: 75 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
import static android.content.Intent.ACTION_SHUTDOWN;
2525
import static android.content.Intent.ACTION_UID_REMOVED;
2626
import static android.content.Intent.EXTRA_UID;
27-
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
2827
import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
28+
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
2929
import static android.net.NetworkStats.IFACE_ALL;
3030
import static android.net.NetworkStats.SET_ALL;
3131
import static android.net.NetworkStats.SET_DEFAULT;
@@ -43,9 +43,12 @@
4343
import static android.provider.Settings.Secure.NETSTATS_TAG_MAX_HISTORY;
4444
import static android.provider.Settings.Secure.NETSTATS_UID_BUCKET_DURATION;
4545
import static android.provider.Settings.Secure.NETSTATS_UID_MAX_HISTORY;
46+
import static android.telephony.PhoneStateListener.LISTEN_DATA_CONNECTION_STATE;
47+
import static android.telephony.PhoneStateListener.LISTEN_NONE;
4648
import static android.text.format.DateUtils.DAY_IN_MILLIS;
4749
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
4850
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
51+
import static android.text.format.DateUtils.SECOND_IN_MILLIS;
4952
import static com.android.internal.util.Preconditions.checkNotNull;
5053
import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
5154
import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
@@ -80,6 +83,7 @@
8083
import android.os.RemoteException;
8184
import android.os.SystemClock;
8285
import android.provider.Settings;
86+
import android.telephony.PhoneStateListener;
8387
import android.telephony.TelephonyManager;
8488
import android.util.EventLog;
8589
import android.util.Log;
@@ -121,7 +125,7 @@
121125
*/
122126
public class NetworkStatsService extends INetworkStatsService.Stub {
123127
private static final String TAG = "NetworkStats";
124-
private static final boolean LOGD = true;
128+
private static final boolean LOGD = false;
125129
private static final boolean LOGV = false;
126130

127131
/** File header magic number: "ANET" */
@@ -132,7 +136,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
132136
private static final int VERSION_UID_WITH_TAG = 3;
133137
private static final int VERSION_UID_WITH_SET = 4;
134138

135-
private static final int MSG_PERFORM_POLL = 0x1;
139+
private static final int MSG_PERFORM_POLL = 1;
140+
private static final int MSG_UPDATE_IFACES = 2;
136141

137142
/** Flags to control detail level of poll event. */
138143
private static final int FLAG_PERSIST_NETWORK = 0x10;
@@ -144,6 +149,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
144149
private final INetworkManagementService mNetworkManager;
145150
private final IAlarmManager mAlarmManager;
146151
private final TrustedTime mTime;
152+
private final TelephonyManager mTeleManager;
147153
private final NetworkStatsSettings mSettings;
148154

149155
private final PowerManager.WakeLock mWakeLock;
@@ -227,6 +233,7 @@ public NetworkStatsService(Context context, INetworkManagementService networkMan
227233
mNetworkManager = checkNotNull(networkManager, "missing INetworkManagementService");
228234
mAlarmManager = checkNotNull(alarmManager, "missing IAlarmManager");
229235
mTime = checkNotNull(time, "missing TrustedTime");
236+
mTeleManager = checkNotNull(TelephonyManager.getDefault(), "missing TelephonyManager");
230237
mSettings = checkNotNull(settings, "missing NetworkStatsSettings");
231238

232239
final PowerManager powerManager = (PowerManager) context.getSystemService(
@@ -279,6 +286,10 @@ public void systemReady() {
279286
// ignored; service lives in system_server
280287
}
281288

289+
// watch for networkType changes that aren't broadcast through
290+
// CONNECTIVITY_ACTION_IMMEDIATE above.
291+
mTeleManager.listen(mPhoneListener, LISTEN_DATA_CONNECTION_STATE);
292+
282293
registerPollAlarmLocked();
283294
registerGlobalAlert();
284295

@@ -288,10 +299,13 @@ public void systemReady() {
288299

289300
private void shutdownLocked() {
290301
mContext.unregisterReceiver(mConnReceiver);
302+
mContext.unregisterReceiver(mTetherReceiver);
291303
mContext.unregisterReceiver(mPollReceiver);
292304
mContext.unregisterReceiver(mRemovedReceiver);
293305
mContext.unregisterReceiver(mShutdownReceiver);
294306

307+
mTeleManager.listen(mPhoneListener, LISTEN_NONE);
308+
295309
writeNetworkStatsLocked();
296310
if (mUidStatsLoaded) {
297311
writeUidStatsLocked();
@@ -535,14 +549,7 @@ public void forceUpdate() {
535549
public void onReceive(Context context, Intent intent) {
536550
// on background handler thread, and verified CONNECTIVITY_INTERNAL
537551
// permission above.
538-
synchronized (mStatsLock) {
539-
mWakeLock.acquire();
540-
try {
541-
updateIfacesLocked();
542-
} finally {
543-
mWakeLock.release();
544-
}
545-
}
552+
updateIfaces();
546553
}
547554
};
548555

@@ -619,6 +626,46 @@ public void limitReached(String limitName, String iface) {
619626
}
620627
};
621628

629+
private int mLastPhoneState = TelephonyManager.DATA_UNKNOWN;
630+
private int mLastPhoneNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
631+
632+
/**
633+
* Receiver that watches for {@link TelephonyManager} changes, such as
634+
* transitioning between network types.
635+
*/
636+
private PhoneStateListener mPhoneListener = new PhoneStateListener() {
637+
@Override
638+
public void onDataConnectionStateChanged(int state, int networkType) {
639+
final boolean stateChanged = state != mLastPhoneState;
640+
final boolean networkTypeChanged = networkType != mLastPhoneNetworkType;
641+
642+
if (networkTypeChanged && !stateChanged) {
643+
// networkType changed without a state change, which means we
644+
// need to roll our own update. delay long enough for
645+
// ConnectivityManager to process.
646+
// TODO: add direct event to ConnectivityService instead of
647+
// relying on this delay.
648+
if (LOGV) Slog.v(TAG, "triggering delayed updateIfaces()");
649+
mHandler.sendMessageDelayed(
650+
mHandler.obtainMessage(MSG_UPDATE_IFACES), SECOND_IN_MILLIS);
651+
}
652+
653+
mLastPhoneState = state;
654+
mLastPhoneNetworkType = networkType;
655+
}
656+
};
657+
658+
private void updateIfaces() {
659+
synchronized (mStatsLock) {
660+
mWakeLock.acquire();
661+
try {
662+
updateIfacesLocked();
663+
} finally {
664+
mWakeLock.release();
665+
}
666+
}
667+
}
668+
622669
/**
623670
* Inspect all current {@link NetworkState} to derive mapping from {@code
624671
* iface} to {@link NetworkStatsHistory}. When multiple {@link NetworkInfo}
@@ -713,19 +760,6 @@ private void performPollLocked(int flags) {
713760
final long threshold = mSettings.getPersistThreshold();
714761

715762
try {
716-
// record network stats
717-
final NetworkStats networkSnapshot = mNetworkManager.getNetworkStatsSummary();
718-
performNetworkPollLocked(networkSnapshot, currentTime);
719-
720-
// persist when enough network data has occurred
721-
final NetworkStats persistNetworkDelta = computeStatsDelta(
722-
mLastPersistNetworkSnapshot, networkSnapshot, true);
723-
final boolean networkPastThreshold = persistNetworkDelta.getTotalBytes() > threshold;
724-
if (persistForce || (persistNetwork && networkPastThreshold)) {
725-
writeNetworkStatsLocked();
726-
mLastPersistNetworkSnapshot = networkSnapshot;
727-
}
728-
729763
// record tethering stats; persisted during normal UID cycle below
730764
final String[] ifacePairs = mConnManager.getTetheredIfacePairs();
731765
final NetworkStats tetherSnapshot = mNetworkManager.getNetworkStatsTethering(
@@ -744,6 +778,19 @@ private void performPollLocked(int flags) {
744778
writeUidStatsLocked();
745779
mLastPersistUidSnapshot = uidSnapshot;
746780
}
781+
782+
// record network stats
783+
final NetworkStats networkSnapshot = mNetworkManager.getNetworkStatsSummary();
784+
performNetworkPollLocked(networkSnapshot, currentTime);
785+
786+
// persist when enough network data has occurred
787+
final NetworkStats persistNetworkDelta = computeStatsDelta(
788+
mLastPersistNetworkSnapshot, networkSnapshot, true);
789+
final boolean networkPastThreshold = persistNetworkDelta.getTotalBytes() > threshold;
790+
if (persistForce || (persistNetwork && networkPastThreshold)) {
791+
writeNetworkStatsLocked();
792+
mLastPersistNetworkSnapshot = networkSnapshot;
793+
}
747794
} catch (IllegalStateException e) {
748795
Log.wtf(TAG, "problem reading network stats", e);
749796
} catch (RemoteException e) {
@@ -1356,6 +1403,10 @@ public boolean handleMessage(Message msg) {
13561403
performPoll(flags);
13571404
return true;
13581405
}
1406+
case MSG_UPDATE_IFACES: {
1407+
updateIfaces();
1408+
return true;
1409+
}
13591410
default: {
13601411
return false;
13611412
}

services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,7 @@ private void expectCurrentTime() throws Exception {
776776
private void expectNetworkStatsPoll() throws Exception {
777777
mNetManager.setGlobalAlert(anyLong());
778778
expectLastCall().anyTimes();
779+
expect(mConnManager.getTetheredIfacePairs()).andReturn(null).anyTimes();
779780
}
780781

781782
private void assertStatsFilesExist(boolean exist) {

0 commit comments

Comments
 (0)