Merge "Merge "Add tether offload traffic to interface stats as well." into oc-mr1-dev am: 21bc3a39a4 am: 1af850fdfe"

This commit is contained in:
Android Build Merger (Role)
2017-08-19 01:16:26 +00:00
committed by Android (Google) Code Review
9 changed files with 89 additions and 27 deletions

View File

@@ -30,7 +30,10 @@ import android.net.NetworkStats;
*/
interface ITetheringStatsProvider {
// 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
// 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. */
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
/**

View File

@@ -281,7 +281,7 @@ interface INetworkManagementService
/**
* Return summary of network statistics all tethering interfaces.
*/
NetworkStats getNetworkStatsTethering();
NetworkStats getNetworkStatsTethering(int how);
/**
* 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_WHITELIST;
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_NONE;
import static android.net.NetworkStats.UID_ALL;
@@ -1863,7 +1864,13 @@ public class NetworkManagementService extends INetworkManagementService.Stub
private class NetdTetheringStatsProvider extends ITetheringStatsProvider.Stub {
@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;
try {
events = mConnector.executeForList("bandwidth", "gettetherstats");
@@ -1906,14 +1913,14 @@ public class NetworkManagementService extends INetworkManagementService.Stub
}
@Override
public NetworkStats getNetworkStatsTethering() {
public NetworkStats getNetworkStatsTethering(int how) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
synchronized (mTetheringStatsProviders) {
for (ITetheringStatsProvider provider: mTetheringStatsProviders.keySet()) {
try {
stats.combineAllValues(provider.getTetherStats());
stats.combineAllValues(provider.getTetherStats(how));
} catch (RemoteException e) {
Log.e(TAG, "Problem reading tethering stats from " +
mTetheringStatsProviders.get(provider) + ": " + e);

View File

@@ -17,7 +17,9 @@
package com.android.server.connectivity.tethering;
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.UID_ALL;
import static android.net.TrafficStats.UID_TETHERING;
import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED;
@@ -202,16 +204,18 @@ public class OffloadController {
private class OffloadTetheringStatsProvider extends ITetheringStatsProvider.Stub {
@Override
public NetworkStats getTetherStats() {
public NetworkStats getTetherStats(int how) {
NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
// 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.
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();
entry.set = SET_DEFAULT;
entry.tag = TAG_NONE;
entry.uid = UID_TETHERING;
entry.uid = (how == STATS_PER_UID) ? UID_TETHERING : UID_ALL;
updateStatsForCurrentUpstream();

View File

@@ -29,6 +29,8 @@ import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.SET_ALL;
import static android.net.NetworkStats.SET_DEFAULT;
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.UID_ALL;
import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
@@ -1041,6 +1043,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final NetworkStats xtSnapshot = getNetworkStatsXt();
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
// can't be reattributed to responsible apps.
@@ -1371,14 +1378,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final NetworkStats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL);
// fold tethering stats and operations into uid snapshot
final NetworkStats tetherSnapshot = getNetworkStatsTethering();
final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_UID);
uidSnapshot.combineAllValues(tetherSnapshot);
final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
Context.TELEPHONY_SERVICE);
// 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) {
uidSnapshot.combineAllValues(vtStats);
}
@@ -1397,7 +1404,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
Context.TELEPHONY_SERVICE);
// Merge video calling data usage into XT
final NetworkStats vtSnapshot = telephonyManager.getVtDataUsage(false);
final NetworkStats vtSnapshot = telephonyManager.getVtDataUsage(STATS_PER_IFACE);
if (vtSnapshot != null) {
xtSnapshot.combineAllValues(vtSnapshot);
}
@@ -1409,9 +1416,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
* Return snapshot of current tethering statistics. Will return empty
* {@link NetworkStats} if any problems are encountered.
*/
private NetworkStats getNetworkStatsTethering() throws RemoteException {
private NetworkStats getNetworkStatsTethering(int how) throws RemoteException {
try {
return mNetworkManager.getNetworkStatsTethering();
return mNetworkManager.getNetworkStatsTethering(how);
} catch (IllegalStateException e) {
Log.wtf(TAG, "problem reading network stats", e);
return new NetworkStats(0L, 10);

View File

@@ -6741,11 +6741,13 @@ public class TelephonyManager {
* Get aggregated video call data usage since boot.
* 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
* @hide
*/
public NetworkStats getVtDataUsage(boolean perUidStats) {
public NetworkStats getVtDataUsage(int how) {
boolean perUidStats = (how == NetworkStats.STATS_PER_UID);
try {
ITelephony service = getITelephony();
if (service != null) {

View File

@@ -17,7 +17,10 @@
package com.android.server.connectivity.tethering;
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.UID_ALL;
import static android.net.TrafficStats.UID_TETHERING;
import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED;
import static com.android.server.connectivity.tethering.OffloadHardwareInterface.ForwardedStats;
@@ -373,7 +376,6 @@ public class OffloadControllerTest {
assertEquals(stats.txBytes, entry.txBytes);
assertEquals(SET_DEFAULT, entry.set);
assertEquals(TAG_NONE, entry.tag);
assertEquals(UID_TETHERING, entry.uid);
}
@Test
@@ -412,20 +414,33 @@ public class OffloadControllerTest {
ethernetStats.txBytes = 100000;
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, perUidStats.size());
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 mobilePosition = 1 - ethernetPosition;
entry = stats.getValues(mobilePosition, entry);
assertNetworkStats(mobileIface, mobileStats, entry);
entry = perUidStats.getValues(mobilePosition, entry);
assertNetworkStats(mobileIface, mobileStats, entry);
ethernetStats.rxBytes = 12345 + 100000;
ethernetStats.txBytes = 54321 + 100000;
entry = stats.getValues(ethernetPosition, entry);
assertNetworkStats(ethernetIface, ethernetStats, entry);
entry = perUidStats.getValues(ethernetPosition, entry);
assertNetworkStats(ethernetIface, ethernetStats, entry);
}
@Test

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_DEFAULT;
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.UID_ALL;
import static android.net.NetworkStatsHistory.FIELD_ALL;
@@ -823,17 +825,24 @@ public class NetworkStatsServiceTest {
incrementCurrentTime(HOUR_IN_MILLIS);
expectCurrentTime();
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)
.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)
.addValues(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L,
0L);
expectNetworkStatsUidDetail(uidStats, tetherIfacePairs, tetherStats);
expectNetworkStatsSummary(ifaceStats, tetherStatsHardware);
expectNetworkStatsUidDetail(uidStats, tetherStats);
forcePollAndWaitForIdle();
// verify service recorded history
@@ -1013,10 +1022,16 @@ public class NetworkStatsServiceTest {
}
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]);
expectNetworkStatsSummaryDev(summary);
expectNetworkStatsSummaryXt(summary);
expectNetworkStatsTethering(STATS_PER_IFACE, tetherStats);
expectNetworkStatsSummaryDev(summary.clone());
expectNetworkStatsSummaryXt(summary.clone());
}
private void expectNetworkStatsSummaryDev(NetworkStats summary) throws Exception {
@@ -1027,17 +1042,21 @@ public class NetworkStatsServiceTest {
when(mNetManager.getNetworkStatsSummaryXt()).thenReturn(summary);
}
private void expectNetworkStatsUidDetail(NetworkStats detail) throws Exception {
expectNetworkStatsUidDetail(detail, new String[0], new NetworkStats(0L, 0));
private void expectNetworkStatsTethering(int how, NetworkStats stats)
throws Exception {
when(mNetManager.getNetworkStatsTethering(how)).thenReturn(stats);
}
private void expectNetworkStatsUidDetail(
NetworkStats detail, String[] tetherIfacePairs, NetworkStats tetherStats)
private void expectNetworkStatsUidDetail(NetworkStats detail) throws Exception {
expectNetworkStatsUidDetail(detail, new NetworkStats(0L, 0));
}
private void expectNetworkStatsUidDetail(NetworkStats detail, NetworkStats tetherStats)
throws Exception {
when(mNetManager.getNetworkStatsUidDetail(UID_ALL)).thenReturn(detail);
// 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 {