Merge changes I325b13d5,I89719fe7 am: 23868e9c09

am: 9335d2d0b1

Change-Id: Iac0d1a08c45816f32b0f8ab81a079883a9965e21
This commit is contained in:
Lorenzo Colitti
2017-08-19 03:25:21 +00:00
committed by android-build-merger
9 changed files with 157 additions and 31 deletions

View File

@@ -30,7 +30,10 @@ import android.net.NetworkStats;
*/ */
interface ITetheringStatsProvider { interface ITetheringStatsProvider {
// Returns cumulative statistics for all tethering sessions since boot, on all upstreams. // Returns cumulative statistics for all tethering sessions since boot, on all upstreams.
NetworkStats getTetherStats(); // @code {how} is one of the NetworkStats.STATS_PER_* constants. If {@code how} is
// {@code STATS_PER_IFACE}, the provider should not include any traffic that is already
// counted by kernel interface counters.
NetworkStats getTetherStats(int how);
// Sets the interface quota for the specified upstream interface. This is defined as the number // Sets the interface quota for the specified upstream interface. This is defined as the number
// of bytes, starting from zero and counting from now, after which data should stop being // of bytes, starting from zero and counting from now, after which data should stop being

View File

@@ -82,6 +82,11 @@ public class NetworkStats implements Parcelable {
/** {@link #roaming} value where roaming data is accounted. */ /** {@link #roaming} value where roaming data is accounted. */
public static final int ROAMING_YES = 1; public static final int ROAMING_YES = 1;
/** Denotes a request for stats at the interface level. */
public static final int STATS_PER_IFACE = 0;
/** Denotes a request for stats at the interface and UID level. */
public static final int STATS_PER_UID = 1;
// TODO: move fields to "mVariable" notation // TODO: move fields to "mVariable" notation
/** /**

View File

@@ -219,6 +219,21 @@ interface INetworkManagementService
*/ */
void unregisterTetheringStatsProvider(ITetheringStatsProvider provider); void unregisterTetheringStatsProvider(ITetheringStatsProvider provider);
/**
* Reports that a tethering provider has reached a data limit.
*
* Currently triggers a global alert, which causes NetworkStatsService to poll counters and
* re-evaluate data usage.
*
* This does not take an interface name because:
* 1. The tethering offload stats provider cannot reliably determine the interface on which the
* limit was reached, because the HAL does not provide it.
* 2. Firing an interface-specific alert instead of a global alert isn't really useful since in
* all cases of interest, the system responds to both in the same way - it polls stats, and
* then notifies NetworkPolicyManagerService of the fact.
*/
void tetherLimitReached(ITetheringStatsProvider provider);
/** /**
** PPPD ** PPPD
**/ **/
@@ -266,7 +281,7 @@ interface INetworkManagementService
/** /**
* Return summary of network statistics all tethering interfaces. * Return summary of network statistics all tethering interfaces.
*/ */
NetworkStats getNetworkStatsTethering(); NetworkStats getNetworkStatsTethering(int how);
/** /**
* Set quota for an interface. * Set quota for an interface.

View File

@@ -34,6 +34,7 @@ import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY;
import static android.net.NetworkPolicyManager.FIREWALL_TYPE_BLACKLIST; import static android.net.NetworkPolicyManager.FIREWALL_TYPE_BLACKLIST;
import static android.net.NetworkPolicyManager.FIREWALL_TYPE_WHITELIST; import static android.net.NetworkPolicyManager.FIREWALL_TYPE_WHITELIST;
import static android.net.NetworkStats.SET_DEFAULT; import static android.net.NetworkStats.SET_DEFAULT;
import static android.net.NetworkStats.STATS_PER_UID;
import static android.net.NetworkStats.TAG_ALL; import static android.net.NetworkStats.TAG_ALL;
import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL; import static android.net.NetworkStats.UID_ALL;
@@ -550,6 +551,18 @@ public class NetworkManagementService extends INetworkManagementService.Stub
} }
} }
@Override
public void tetherLimitReached(ITetheringStatsProvider provider) {
mContext.enforceCallingOrSelfPermission(NETWORK_STACK, TAG);
synchronized(mTetheringStatsProviders) {
if (!mTetheringStatsProviders.containsKey(provider)) {
return;
}
// No current code examines the interface parameter in a global alert. Just pass null.
notifyLimitReached(LIMIT_GLOBAL_ALERT, null);
}
}
// Sync the state of the given chain with the native daemon. // Sync the state of the given chain with the native daemon.
private void syncFirewallChainLocked(int chain, String name) { private void syncFirewallChainLocked(int chain, String name) {
SparseIntArray rules; SparseIntArray rules;
@@ -1851,7 +1864,13 @@ public class NetworkManagementService extends INetworkManagementService.Stub
private class NetdTetheringStatsProvider extends ITetheringStatsProvider.Stub { private class NetdTetheringStatsProvider extends ITetheringStatsProvider.Stub {
@Override @Override
public NetworkStats getTetherStats() { public NetworkStats getTetherStats(int how) {
// We only need to return per-UID stats. Per-device stats are already counted by
// interface counters.
if (how != STATS_PER_UID) {
return new NetworkStats(SystemClock.elapsedRealtime(), 0);
}
final NativeDaemonEvent[] events; final NativeDaemonEvent[] events;
try { try {
events = mConnector.executeForList("bandwidth", "gettetherstats"); events = mConnector.executeForList("bandwidth", "gettetherstats");
@@ -1894,14 +1913,14 @@ public class NetworkManagementService extends INetworkManagementService.Stub
} }
@Override @Override
public NetworkStats getNetworkStatsTethering() { public NetworkStats getNetworkStatsTethering(int how) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1); final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
synchronized (mTetheringStatsProviders) { synchronized (mTetheringStatsProviders) {
for (ITetheringStatsProvider provider: mTetheringStatsProviders.keySet()) { for (ITetheringStatsProvider provider: mTetheringStatsProviders.keySet()) {
try { try {
stats.combineAllValues(provider.getTetherStats()); stats.combineAllValues(provider.getTetherStats(how));
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "Problem reading tethering stats from " + Log.e(TAG, "Problem reading tethering stats from " +
mTetheringStatsProviders.get(provider) + ": " + e); mTetheringStatsProviders.get(provider) + ": " + e);

View File

@@ -17,7 +17,9 @@
package com.android.server.connectivity.tethering; package com.android.server.connectivity.tethering;
import static android.net.NetworkStats.SET_DEFAULT; import static android.net.NetworkStats.SET_DEFAULT;
import static android.net.NetworkStats.STATS_PER_UID;
import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
import static android.net.TrafficStats.UID_TETHERING; import static android.net.TrafficStats.UID_TETHERING;
import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED; import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED;
@@ -60,6 +62,8 @@ public class OffloadController {
private final Handler mHandler; private final Handler mHandler;
private final OffloadHardwareInterface mHwInterface; private final OffloadHardwareInterface mHwInterface;
private final ContentResolver mContentResolver; private final ContentResolver mContentResolver;
private final INetworkManagementService mNms;
private final ITetheringStatsProvider mStatsProvider;
private final SharedLog mLog; private final SharedLog mLog;
private boolean mConfigInitialized; private boolean mConfigInitialized;
private boolean mControlInitialized; private boolean mControlInitialized;
@@ -89,13 +93,14 @@ public class OffloadController {
mHandler = h; mHandler = h;
mHwInterface = hwi; mHwInterface = hwi;
mContentResolver = contentResolver; mContentResolver = contentResolver;
mNms = nms;
mStatsProvider = new OffloadTetheringStatsProvider();
mLog = log.forSubComponent(TAG); mLog = log.forSubComponent(TAG);
mExemptPrefixes = new HashSet<>(); mExemptPrefixes = new HashSet<>();
mLastLocalPrefixStrs = new HashSet<>(); mLastLocalPrefixStrs = new HashSet<>();
try { try {
nms.registerTetheringStatsProvider( mNms.registerTetheringStatsProvider(mStatsProvider, getClass().getSimpleName());
new OffloadTetheringStatsProvider(), getClass().getSimpleName());
} catch (RemoteException e) { } catch (RemoteException e) {
mLog.e("Cannot register offload stats provider: " + e); mLog.e("Cannot register offload stats provider: " + e);
} }
@@ -150,7 +155,26 @@ public class OffloadController {
@Override @Override
public void onStoppedLimitReached() { public void onStoppedLimitReached() {
mLog.log("onStoppedLimitReached"); mLog.log("onStoppedLimitReached");
// Poll for statistics and notify NetworkStats
// We cannot reliably determine on which interface the limit was reached,
// because the HAL interface does not specify it. We cannot just use the
// current upstream, because that might have changed since the time that
// the HAL queued the callback.
// TODO: rev the HAL so that it provides an interface name.
// Fetch current stats, so that when our notification reaches
// NetworkStatsService and triggers a poll, we will respond with
// current data (which will be above the limit that was reached).
// Note that if we just changed upstream, this is unnecessary but harmless.
// The stats for the previous upstream were already updated on this thread
// just after the upstream was changed, so they are also up-to-date.
updateStatsForCurrentUpstream();
try {
mNms.tetherLimitReached(mStatsProvider);
} catch (RemoteException e) {
mLog.e("Cannot report data limit reached: " + e);
}
} }
@Override @Override
@@ -180,16 +204,18 @@ public class OffloadController {
private class OffloadTetheringStatsProvider extends ITetheringStatsProvider.Stub { private class OffloadTetheringStatsProvider extends ITetheringStatsProvider.Stub {
@Override @Override
public NetworkStats getTetherStats() { public NetworkStats getTetherStats(int how) {
NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0); NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
// We can't just post to mHandler because we are mostly (but not always) called by // We can't just post to mHandler because we are mostly (but not always) called by
// NetworkStatsService#performPollLocked, which is (currently) on the same thread as us. // NetworkStatsService#performPollLocked, which is (currently) on the same thread as us.
mHandler.runWithScissors(() -> { mHandler.runWithScissors(() -> {
// We have to report both per-interface and per-UID stats, because offloaded traffic
// is not seen by kernel interface counters.
NetworkStats.Entry entry = new NetworkStats.Entry(); NetworkStats.Entry entry = new NetworkStats.Entry();
entry.set = SET_DEFAULT; entry.set = SET_DEFAULT;
entry.tag = TAG_NONE; entry.tag = TAG_NONE;
entry.uid = UID_TETHERING; entry.uid = (how == STATS_PER_UID) ? UID_TETHERING : UID_ALL;
updateStatsForCurrentUpstream(); updateStatsForCurrentUpstream();

View File

@@ -31,6 +31,8 @@ import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.SET_ALL; import static android.net.NetworkStats.SET_ALL;
import static android.net.NetworkStats.SET_DEFAULT; import static android.net.NetworkStats.SET_DEFAULT;
import static android.net.NetworkStats.SET_FOREGROUND; import static android.net.NetworkStats.SET_FOREGROUND;
import static android.net.NetworkStats.STATS_PER_IFACE;
import static android.net.NetworkStats.STATS_PER_UID;
import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL; import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkTemplate.buildTemplateMobileWildcard; import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
@@ -1042,6 +1044,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final NetworkStats xtSnapshot = getNetworkStatsXt(); final NetworkStats xtSnapshot = getNetworkStatsXt();
final NetworkStats devSnapshot = mNetworkManager.getNetworkStatsSummaryDev(); final NetworkStats devSnapshot = mNetworkManager.getNetworkStatsSummaryDev();
// Tethering snapshot for dev and xt stats. Counts per-interface data from tethering stats
// providers that isn't already counted by dev and XT stats.
final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_IFACE);
xtSnapshot.combineAllValues(tetherSnapshot);
devSnapshot.combineAllValues(tetherSnapshot);
// For xt/dev, we pass a null VPN array because usage is aggregated by UID, so VPN traffic // For xt/dev, we pass a null VPN array because usage is aggregated by UID, so VPN traffic
// can't be reattributed to responsible apps. // can't be reattributed to responsible apps.
@@ -1372,14 +1379,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final NetworkStats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL); final NetworkStats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL);
// fold tethering stats and operations into uid snapshot // fold tethering stats and operations into uid snapshot
final NetworkStats tetherSnapshot = getNetworkStatsTethering(); final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_UID);
uidSnapshot.combineAllValues(tetherSnapshot); uidSnapshot.combineAllValues(tetherSnapshot);
final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService( final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
Context.TELEPHONY_SERVICE); Context.TELEPHONY_SERVICE);
// fold video calling data usage stats into uid snapshot // fold video calling data usage stats into uid snapshot
final NetworkStats vtStats = telephonyManager.getVtDataUsage(true); final NetworkStats vtStats = telephonyManager.getVtDataUsage(STATS_PER_UID);
if (vtStats != null) { if (vtStats != null) {
uidSnapshot.combineAllValues(vtStats); uidSnapshot.combineAllValues(vtStats);
} }
@@ -1398,7 +1405,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
Context.TELEPHONY_SERVICE); Context.TELEPHONY_SERVICE);
// Merge video calling data usage into XT // Merge video calling data usage into XT
final NetworkStats vtSnapshot = telephonyManager.getVtDataUsage(false); final NetworkStats vtSnapshot = telephonyManager.getVtDataUsage(STATS_PER_IFACE);
if (vtSnapshot != null) { if (vtSnapshot != null) {
xtSnapshot.combineAllValues(vtSnapshot); xtSnapshot.combineAllValues(vtSnapshot);
} }
@@ -1410,9 +1417,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
* Return snapshot of current tethering statistics. Will return empty * Return snapshot of current tethering statistics. Will return empty
* {@link NetworkStats} if any problems are encountered. * {@link NetworkStats} if any problems are encountered.
*/ */
private NetworkStats getNetworkStatsTethering() throws RemoteException { private NetworkStats getNetworkStatsTethering(int how) throws RemoteException {
try { try {
return mNetworkManager.getNetworkStatsTethering(); return mNetworkManager.getNetworkStatsTethering(how);
} catch (IllegalStateException e) { } catch (IllegalStateException e) {
Log.wtf(TAG, "problem reading network stats", e); Log.wtf(TAG, "problem reading network stats", e);
return new NetworkStats(0L, 10); return new NetworkStats(0L, 10);

View File

@@ -6649,11 +6649,13 @@ public class TelephonyManager {
* Get aggregated video call data usage since boot. * Get aggregated video call data usage since boot.
* Permissions android.Manifest.permission.READ_NETWORK_USAGE_HISTORY is required. * Permissions android.Manifest.permission.READ_NETWORK_USAGE_HISTORY is required.
* *
* @param perUidStats True if requesting data usage per uid, otherwise overall usage. * @param how one of the NetworkStats.STATS_PER_* constants depending on whether the request is
* for data usage per uid or overall usage.
* @return Snapshot of video call data usage * @return Snapshot of video call data usage
* @hide * @hide
*/ */
public NetworkStats getVtDataUsage(boolean perUidStats) { public NetworkStats getVtDataUsage(int how) {
boolean perUidStats = (how == NetworkStats.STATS_PER_UID);
try { try {
ITelephony service = getITelephony(); ITelephony service = getITelephony();
if (service != null) { if (service != null) {

View File

@@ -17,7 +17,10 @@
package com.android.server.connectivity.tethering; package com.android.server.connectivity.tethering;
import static android.net.NetworkStats.SET_DEFAULT; import static android.net.NetworkStats.SET_DEFAULT;
import static android.net.NetworkStats.STATS_PER_IFACE;
import static android.net.NetworkStats.STATS_PER_UID;
import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
import static android.net.TrafficStats.UID_TETHERING; import static android.net.TrafficStats.UID_TETHERING;
import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED; import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED;
import static com.android.server.connectivity.tethering.OffloadHardwareInterface.ForwardedStats; import static com.android.server.connectivity.tethering.OffloadHardwareInterface.ForwardedStats;
@@ -85,6 +88,8 @@ public class OffloadControllerTest {
ArgumentCaptor.forClass(ArrayList.class); ArgumentCaptor.forClass(ArrayList.class);
private final ArgumentCaptor<ITetheringStatsProvider.Stub> mTetherStatsProviderCaptor = private final ArgumentCaptor<ITetheringStatsProvider.Stub> mTetherStatsProviderCaptor =
ArgumentCaptor.forClass(ITetheringStatsProvider.Stub.class); ArgumentCaptor.forClass(ITetheringStatsProvider.Stub.class);
private final ArgumentCaptor<OffloadHardwareInterface.ControlCallback> mControlCallbackCaptor =
ArgumentCaptor.forClass(OffloadHardwareInterface.ControlCallback.class);
private MockContentResolver mContentResolver; private MockContentResolver mContentResolver;
@Before public void setUp() { @Before public void setUp() {
@@ -105,7 +110,7 @@ public class OffloadControllerTest {
private void setupFunctioningHardwareInterface() { private void setupFunctioningHardwareInterface() {
when(mHardware.initOffloadConfig()).thenReturn(true); when(mHardware.initOffloadConfig()).thenReturn(true);
when(mHardware.initOffloadControl(any(OffloadHardwareInterface.ControlCallback.class))) when(mHardware.initOffloadControl(mControlCallbackCaptor.capture()))
.thenReturn(true); .thenReturn(true);
when(mHardware.getForwardedStats(any())).thenReturn(new ForwardedStats()); when(mHardware.getForwardedStats(any())).thenReturn(new ForwardedStats());
} }
@@ -375,7 +380,6 @@ public class OffloadControllerTest {
assertEquals(stats.txBytes, entry.txBytes); assertEquals(stats.txBytes, entry.txBytes);
assertEquals(SET_DEFAULT, entry.set); assertEquals(SET_DEFAULT, entry.set);
assertEquals(TAG_NONE, entry.tag); assertEquals(TAG_NONE, entry.tag);
assertEquals(UID_TETHERING, entry.uid);
} }
@Test @Test
@@ -414,20 +418,33 @@ public class OffloadControllerTest {
ethernetStats.txBytes = 100000; ethernetStats.txBytes = 100000;
offload.setUpstreamLinkProperties(null); offload.setUpstreamLinkProperties(null);
NetworkStats stats = mTetherStatsProviderCaptor.getValue().getTetherStats(); ITetheringStatsProvider provider = mTetherStatsProviderCaptor.getValue();
NetworkStats stats = provider.getTetherStats(STATS_PER_IFACE);
NetworkStats perUidStats = provider.getTetherStats(STATS_PER_UID);
assertEquals(2, stats.size()); assertEquals(2, stats.size());
assertEquals(2, perUidStats.size());
NetworkStats.Entry entry = null; NetworkStats.Entry entry = null;
for (int i = 0; i < stats.size(); i++) {
assertEquals(UID_ALL, stats.getValues(i, entry).uid);
assertEquals(UID_TETHERING, perUidStats.getValues(i, entry).uid);
}
int ethernetPosition = ethernetIface.equals(stats.getValues(0, entry).iface) ? 0 : 1; int ethernetPosition = ethernetIface.equals(stats.getValues(0, entry).iface) ? 0 : 1;
int mobilePosition = 1 - ethernetPosition; int mobilePosition = 1 - ethernetPosition;
entry = stats.getValues(mobilePosition, entry); entry = stats.getValues(mobilePosition, entry);
assertNetworkStats(mobileIface, mobileStats, entry); assertNetworkStats(mobileIface, mobileStats, entry);
entry = perUidStats.getValues(mobilePosition, entry);
assertNetworkStats(mobileIface, mobileStats, entry);
ethernetStats.rxBytes = 12345 + 100000; ethernetStats.rxBytes = 12345 + 100000;
ethernetStats.txBytes = 54321 + 100000; ethernetStats.txBytes = 54321 + 100000;
entry = stats.getValues(ethernetPosition, entry); entry = stats.getValues(ethernetPosition, entry);
assertNetworkStats(ethernetIface, ethernetStats, entry); assertNetworkStats(ethernetIface, ethernetStats, entry);
entry = perUidStats.getValues(ethernetPosition, entry);
assertNetworkStats(ethernetIface, ethernetStats, entry);
} }
@Test @Test
@@ -493,4 +510,17 @@ public class OffloadControllerTest {
waitForIdle(); waitForIdle();
inOrder.verify(mHardware).stopOffloadControl(); inOrder.verify(mHardware).stopOffloadControl();
} }
@Test
public void testDataLimitCallback() throws Exception {
setupFunctioningHardwareInterface();
enableOffload();
final OffloadController offload = makeOffloadController();
offload.start();
OffloadHardwareInterface.ControlCallback callback = mControlCallbackCaptor.getValue();
callback.onStoppedLimitReached();
verify(mNMService, times(1)).tetherLimitReached(mTetherStatsProviderCaptor.getValue());
}
} }

View File

@@ -31,6 +31,8 @@ import static android.net.NetworkStats.ROAMING_YES;
import static android.net.NetworkStats.SET_ALL; import static android.net.NetworkStats.SET_ALL;
import static android.net.NetworkStats.SET_DEFAULT; import static android.net.NetworkStats.SET_DEFAULT;
import static android.net.NetworkStats.SET_FOREGROUND; import static android.net.NetworkStats.SET_FOREGROUND;
import static android.net.NetworkStats.STATS_PER_IFACE;
import static android.net.NetworkStats.STATS_PER_UID;
import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL; import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkStatsHistory.FIELD_ALL; import static android.net.NetworkStatsHistory.FIELD_ALL;
@@ -823,17 +825,24 @@ public class NetworkStatsServiceTest {
incrementCurrentTime(HOUR_IN_MILLIS); incrementCurrentTime(HOUR_IN_MILLIS);
expectCurrentTime(); expectCurrentTime();
expectDefaultSettings(); expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
// Traffic seen by kernel counters (includes software tethering).
final NetworkStats ifaceStats = new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 1536L, 12L, 384L, 3L);
// Hardware tethering traffic, not seen by kernel counters.
final NetworkStats tetherStatsHardware = new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 512L, 4L, 128L, 1L);
// Traffic for UID_RED.
final NetworkStats uidStats = new NetworkStats(getElapsedRealtime(), 1) final NetworkStats uidStats = new NetworkStats(getElapsedRealtime(), 1)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L); .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L);
final String[] tetherIfacePairs = new String[] { TEST_IFACE, "wlan0" }; // All tethering traffic, both hardware and software.
final NetworkStats tetherStats = new NetworkStats(getElapsedRealtime(), 1) final NetworkStats tetherStats = new NetworkStats(getElapsedRealtime(), 1)
.addValues(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L, .addValues(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L,
0L); 0L);
expectNetworkStatsUidDetail(uidStats, tetherIfacePairs, tetherStats); expectNetworkStatsSummary(ifaceStats, tetherStatsHardware);
expectNetworkStatsUidDetail(uidStats, tetherStats);
forcePollAndWaitForIdle(); forcePollAndWaitForIdle();
// verify service recorded history // verify service recorded history
@@ -1013,10 +1022,16 @@ public class NetworkStatsServiceTest {
} }
private void expectNetworkStatsSummary(NetworkStats summary) throws Exception { private void expectNetworkStatsSummary(NetworkStats summary) throws Exception {
expectNetworkStatsSummary(summary, new NetworkStats(0L, 0));
}
private void expectNetworkStatsSummary(NetworkStats summary, NetworkStats tetherStats)
throws Exception {
when(mConnManager.getAllVpnInfo()).thenReturn(new VpnInfo[0]); when(mConnManager.getAllVpnInfo()).thenReturn(new VpnInfo[0]);
expectNetworkStatsSummaryDev(summary); expectNetworkStatsTethering(STATS_PER_IFACE, tetherStats);
expectNetworkStatsSummaryXt(summary); expectNetworkStatsSummaryDev(summary.clone());
expectNetworkStatsSummaryXt(summary.clone());
} }
private void expectNetworkStatsSummaryDev(NetworkStats summary) throws Exception { private void expectNetworkStatsSummaryDev(NetworkStats summary) throws Exception {
@@ -1027,17 +1042,21 @@ public class NetworkStatsServiceTest {
when(mNetManager.getNetworkStatsSummaryXt()).thenReturn(summary); when(mNetManager.getNetworkStatsSummaryXt()).thenReturn(summary);
} }
private void expectNetworkStatsUidDetail(NetworkStats detail) throws Exception { private void expectNetworkStatsTethering(int how, NetworkStats stats)
expectNetworkStatsUidDetail(detail, new String[0], new NetworkStats(0L, 0)); throws Exception {
when(mNetManager.getNetworkStatsTethering(how)).thenReturn(stats);
} }
private void expectNetworkStatsUidDetail( private void expectNetworkStatsUidDetail(NetworkStats detail) throws Exception {
NetworkStats detail, String[] tetherIfacePairs, NetworkStats tetherStats) expectNetworkStatsUidDetail(detail, new NetworkStats(0L, 0));
}
private void expectNetworkStatsUidDetail(NetworkStats detail, NetworkStats tetherStats)
throws Exception { throws Exception {
when(mNetManager.getNetworkStatsUidDetail(UID_ALL)).thenReturn(detail); when(mNetManager.getNetworkStatsUidDetail(UID_ALL)).thenReturn(detail);
// also include tethering details, since they are folded into UID // also include tethering details, since they are folded into UID
when(mNetManager.getNetworkStatsTethering()).thenReturn(tetherStats); when(mNetManager.getNetworkStatsTethering(STATS_PER_UID)).thenReturn(tetherStats);
} }
private void expectDefaultSettings() throws Exception { private void expectDefaultSettings() throws Exception {