Loading core/java/android/net/LinkProperties.java +6 −3 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.net; import android.annotation.NonNull; import android.net.ProxyInfo; import android.os.Parcelable; import android.os.Parcel; Loading @@ -24,7 +25,6 @@ import android.text.TextUtils; import java.net.InetAddress; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collection; Loading Loading @@ -480,7 +480,10 @@ public final class LinkProperties implements Parcelable { * Returns all the links stacked on top of this link. * @hide */ public List<LinkProperties> getStackedLinks() { public @NonNull List<LinkProperties> getStackedLinks() { if (mStackedLinks.isEmpty()) { return Collections.EMPTY_LIST; } List<LinkProperties> stacked = new ArrayList<LinkProperties>(); for (LinkProperties link : mStackedLinks.values()) { stacked.add(new LinkProperties(link)); Loading core/java/com/android/internal/net/NetworkStatsFactory.java +66 −4 Original line number Diff line number Diff line Loading @@ -25,17 +25,20 @@ import static com.android.server.NetworkManagementSocketTagger.kernelToTag; import android.net.NetworkStats; import android.os.StrictMode; import android.os.SystemClock; import android.util.ArrayMap; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.internal.util.ProcFileReader; import libcore.io.IoUtils; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.ProtocolException; import libcore.io.IoUtils; import java.util.Objects; /** * Creates {@link NetworkStats} instances by parsing various {@code /proc/} Loading @@ -54,6 +57,19 @@ public class NetworkStatsFactory { /** Path to {@code /proc/net/xt_qtaguid/stats}. */ private final File mStatsXtUid; @GuardedBy("sStackedIfaces") private static final ArrayMap<String, String> sStackedIfaces = new ArrayMap<>(); public static void noteStackedIface(String stackedIface, String baseIface) { synchronized (sStackedIfaces) { if (baseIface != null) { sStackedIfaces.put(stackedIface, baseIface); } else { sStackedIfaces.remove(stackedIface); } } } public NetworkStatsFactory() { this(new File("/proc/")); } Loading Loading @@ -171,8 +187,54 @@ public class NetworkStatsFactory { } public NetworkStats readNetworkStatsDetail(int limitUid, String[] limitIfaces, int limitTag, NetworkStats lastStats) throws IOException { NetworkStats lastStats) throws IOException { final NetworkStats stats = readNetworkStatsDetailInternal(limitUid, limitIfaces, limitTag, lastStats); synchronized (sStackedIfaces) { // Sigh, xt_qtaguid ends up double-counting tx traffic going through // clatd interfaces, so we need to subtract it here. final int size = sStackedIfaces.size(); for (int i = 0; i < size; i++) { final String stackedIface = sStackedIfaces.keyAt(i); final String baseIface = sStackedIfaces.valueAt(i); // Count up the tx traffic and subtract from root UID on the // base interface. NetworkStats.Entry adjust = new NetworkStats.Entry(baseIface, 0, 0, 0, 0L, 0L, 0L, 0L, 0L); NetworkStats.Entry entry = null; for (int j = 0; j < stats.size(); j++) { entry = stats.getValues(j, entry); if (Objects.equals(entry.iface, stackedIface)) { adjust.txBytes -= entry.txBytes; adjust.txPackets -= entry.txPackets; } } stats.combineValues(adjust); } } // Double sigh, all rx traffic on clat needs to be tweaked to // account for the dropped IPv6 header size post-unwrap. NetworkStats.Entry entry = null; for (int i = 0; i < stats.size(); i++) { entry = stats.getValues(i, entry); if (entry.iface != null && entry.iface.startsWith("clat")) { // Delta between IPv4 header (20b) and IPv6 header (40b) entry.rxBytes = entry.rxPackets * 20; entry.rxPackets = 0; entry.txBytes = 0; entry.txPackets = 0; stats.combineValues(entry); } } return stats; } private NetworkStats readNetworkStatsDetailInternal(int limitUid, String[] limitIfaces, int limitTag, NetworkStats lastStats) throws IOException { if (USE_NATIVE_PARSING) { final NetworkStats stats; if (lastStats != null) { Loading services/core/java/com/android/server/ConnectivityService.java +18 −5 Original line number Diff line number Diff line Loading @@ -119,7 +119,9 @@ import android.util.Xml; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.app.IBatteryStats; import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.NetworkStatsFactory; import com.android.internal.net.VpnConfig; import com.android.internal.net.VpnProfile; import com.android.internal.telephony.DctConstants; Loading Loading @@ -4476,12 +4478,23 @@ public class ConnectivityService extends IConnectivityManager.Stub { // TODO - read the tcp buffer size config string from somewhere // updateNetworkSettings(); } // notify battery stats service about this network // Notify battery stats service about this network, both the normal // interface and any stacked links. try { BatteryStatsService.getService().noteNetworkInterfaceType( newNetwork.linkProperties.getInterfaceName(), newNetwork.networkInfo.getType()); } catch (RemoteException e) { } final IBatteryStats bs = BatteryStatsService.getService(); final int type = newNetwork.networkInfo.getType(); final String baseIface = newNetwork.linkProperties.getInterfaceName(); bs.noteNetworkInterfaceType(baseIface, type); for (LinkProperties stacked : newNetwork.linkProperties.getStackedLinks()) { final String stackedIface = stacked.getInterfaceName(); bs.noteNetworkInterfaceType(stackedIface, type); NetworkStatsFactory.noteStackedIface(stackedIface, baseIface); } } catch (RemoteException ignored) { } notifyNetworkCallbacks(newNetwork, ConnectivityManager.CALLBACK_AVAILABLE); } else { if (DBG && newNetwork.networkRequests.size() != 0) { Loading services/core/java/com/android/server/net/NetworkPolicyManagerService.java +31 −19 Original line number Diff line number Diff line Loading @@ -38,8 +38,8 @@ import static android.net.NetworkPolicy.LIMIT_DISABLED; import static android.net.NetworkPolicy.SNOOZE_NEVER; import static android.net.NetworkPolicy.WARNING_DISABLED; import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE; import static android.net.NetworkPolicyManager.POLICY_NONE; import static android.net.NetworkPolicyManager.POLICY_ALLOW_BACKGROUND_BATTERY_SAVE; import static android.net.NetworkPolicyManager.POLICY_NONE; import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; Loading Loading @@ -96,6 +96,7 @@ import android.net.INetworkManagementEventObserver; import android.net.INetworkPolicyListener; import android.net.INetworkPolicyManager; import android.net.INetworkStatsService; import android.net.LinkProperties; import android.net.NetworkIdentity; import android.net.NetworkInfo; import android.net.NetworkPolicy; Loading Loading @@ -127,6 +128,7 @@ import android.util.ArraySet; import android.util.AtomicFile; import android.util.Log; import android.util.NtpTrustedTime; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; Loading @@ -142,6 +144,8 @@ import com.android.server.LocalServices; import com.android.server.SystemConfig; import com.google.android.collect.Lists; import libcore.io.IoUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; Loading @@ -158,8 +162,6 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; import libcore.io.IoUtils; /** * Service that maintains low-level network policy rules, using * {@link NetworkStatsService} statistics to drive those rules. Loading Loading @@ -1049,36 +1051,44 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // use over those networks can have a cost associated with it). final boolean powerSave = mRestrictPower && !mRestrictBackground; // first, derive identity for all connected networks, which can be used // to match against templates. final ArrayMap<NetworkIdentity, String> networks = new ArrayMap<NetworkIdentity, String>(states.length); // First, generate identities of all connected networks so we can // quickly compare them against all defined policies below. final ArrayList<Pair<String, NetworkIdentity>> connIdents = new ArrayList<>(states.length); final ArraySet<String> connIfaces = new ArraySet<String>(states.length); for (NetworkState state : states) { // stash identity and iface away for later use if (state.networkInfo.isConnected()) { final String iface = state.linkProperties.getInterfaceName(); final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); networks.put(ident, iface); final String baseIface = state.linkProperties.getInterfaceName(); connIdents.add(Pair.create(baseIface, ident)); if (powerSave) { connIfaces.add(iface); connIfaces.add(baseIface); } // Stacked interfaces are considered to have same identity as // their parent network. final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks(); for (LinkProperties stackedLink : stackedLinks) { final String stackedIface = stackedLink.getInterfaceName(); connIdents.add(Pair.create(stackedIface, ident)); if (powerSave) { connIfaces.add(stackedIface); } } } } // build list of rules and ifaces to enforce them against // Apply policies against all connected interfaces found above mNetworkRules.clear(); final ArrayList<String> ifaceList = Lists.newArrayList(); for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) { final NetworkPolicy policy = mNetworkPolicy.valueAt(i); // collect all active ifaces that match this template ifaceList.clear(); for (int j = networks.size()-1; j >= 0; j--) { final NetworkIdentity ident = networks.keyAt(j); if (policy.template.matches(ident)) { final String iface = networks.valueAt(j); ifaceList.add(iface); for (int j = connIdents.size() - 1; j >= 0; j--) { final Pair<String, NetworkIdentity> ident = connIdents.get(j); if (policy.template.matches(ident.second)) { ifaceList.add(ident.first); } } Loading Loading @@ -1787,6 +1797,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } fout.decreaseIndent(); fout.print("Metered ifaces: "); fout.println(String.valueOf(mMeteredIfaces)); fout.println("Policy for UIDs:"); fout.increaseIndent(); int size = mUidPolicy.size(); Loading services/core/java/com/android/server/net/NetworkStatsService.java +58 −27 Original line number Diff line number Diff line Loading @@ -62,8 +62,6 @@ 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.ArrayUtils.appendElement; import static com.android.internal.util.ArrayUtils.contains; import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT; import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats; Loading Loading @@ -107,6 +105,8 @@ import android.provider.Settings; import android.provider.Settings.Global; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.util.ArrayMap; import android.util.ArraySet; import android.util.EventLog; import android.util.Log; import android.util.MathUtils; Loading @@ -121,14 +121,12 @@ import com.android.internal.util.FileRotator; import com.android.internal.util.IndentingPrintWriter; import com.android.server.EventLogTags; import com.android.server.connectivity.Tethering; import com.google.android.collect.Maps; import java.io.File; import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; Loading Loading @@ -215,7 +213,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private final Object mStatsLock = new Object(); /** Set of currently active ifaces. */ private HashMap<String, NetworkIdentitySet> mActiveIfaces = Maps.newHashMap(); private final ArrayMap<String, NetworkIdentitySet> mActiveIfaces = new ArrayMap<>(); /** Set of currently active ifaces for UID stats. */ private final ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces = new ArrayMap<>(); /** Current default active iface. */ private String mActiveIface; /** Set of any ifaces associated with mobile networks since boot. */ Loading Loading @@ -883,30 +883,52 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mActiveIface = activeLink != null ? activeLink.getInterfaceName() : null; // rebuild active interfaces based on connected networks // Rebuild active interfaces based on connected networks mActiveIfaces.clear(); mActiveUidIfaces.clear(); final ArraySet<String> mobileIfaces = new ArraySet<>(); for (NetworkState state : states) { if (state.networkInfo.isConnected()) { // collect networks under their parent interfaces final String iface = state.linkProperties.getInterfaceName(); final boolean isMobile = isNetworkTypeMobile(state.networkInfo.getType()); final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); NetworkIdentitySet ident = mActiveIfaces.get(iface); if (ident == null) { ident = new NetworkIdentitySet(); mActiveIfaces.put(iface, ident); // Traffic occurring on the base interface is always counted for // both total usage and UID details. final String baseIface = state.linkProperties.getInterfaceName(); findOrCreateNetworkIdentitySet(mActiveIfaces, baseIface).add(ident); findOrCreateNetworkIdentitySet(mActiveUidIfaces, baseIface).add(ident); if (isMobile) { mobileIfaces.add(baseIface); } ident.add(NetworkIdentity.buildNetworkIdentity(mContext, state)); // remember any ifaces associated with mobile networks if (isNetworkTypeMobile(state.networkInfo.getType()) && iface != null) { if (!contains(mMobileIfaces, iface)) { mMobileIfaces = appendElement(String.class, mMobileIfaces, iface); // Traffic occurring on stacked interfaces is usually clatd, // which is already accounted against its final egress interface // by the kernel. Thus, we only need to collect stacked // interface stats at the UID level. final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks(); for (LinkProperties stackedLink : stackedLinks) { final String stackedIface = stackedLink.getInterfaceName(); findOrCreateNetworkIdentitySet(mActiveUidIfaces, stackedIface).add(ident); if (isMobile) { mobileIfaces.add(stackedIface); } } } } mobileIfaces.remove(null); mMobileIfaces = mobileIfaces.toArray(new String[mobileIfaces.size()]); } private static <K> NetworkIdentitySet findOrCreateNetworkIdentitySet( ArrayMap<K, NetworkIdentitySet> map, K key) { NetworkIdentitySet ident = map.get(key); if (ident == null) { ident = new NetworkIdentitySet(); map.put(key, ident); } return ident; } /** Loading @@ -926,8 +948,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime); mXtRecorder.recordSnapshotLocked(xtSnapshot, mActiveIfaces, currentTime); mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime); mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime); mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime); mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime); } catch (IllegalStateException e) { Slog.w(TAG, "problem reading network stats: " + e); Loading Loading @@ -980,8 +1002,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime); mXtRecorder.recordSnapshotLocked(xtSnapshot, mActiveIfaces, currentTime); mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime); mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime); mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime); mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime); } catch (IllegalStateException e) { Log.wtf(TAG, "problem reading network stats", e); Loading Loading @@ -1136,10 +1158,19 @@ public class NetworkStatsService extends INetworkStatsService.Stub { pw.println("Active interfaces:"); pw.increaseIndent(); for (String iface : mActiveIfaces.keySet()) { final NetworkIdentitySet ident = mActiveIfaces.get(iface); pw.print("iface="); pw.print(iface); pw.print(" ident="); pw.println(ident.toString()); for (int i = 0; i < mActiveIfaces.size(); i++) { pw.printPair("iface", mActiveIfaces.keyAt(i)); pw.printPair("ident", mActiveIfaces.valueAt(i)); pw.println(); } pw.decreaseIndent(); pw.println("Active UID interfaces:"); pw.increaseIndent(); for (int i = 0; i < mActiveUidIfaces.size(); i++) { pw.printPair("iface", mActiveUidIfaces.keyAt(i)); pw.printPair("ident", mActiveUidIfaces.valueAt(i)); pw.println(); } pw.decreaseIndent(); Loading Loading
core/java/android/net/LinkProperties.java +6 −3 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.net; import android.annotation.NonNull; import android.net.ProxyInfo; import android.os.Parcelable; import android.os.Parcel; Loading @@ -24,7 +25,6 @@ import android.text.TextUtils; import java.net.InetAddress; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collection; Loading Loading @@ -480,7 +480,10 @@ public final class LinkProperties implements Parcelable { * Returns all the links stacked on top of this link. * @hide */ public List<LinkProperties> getStackedLinks() { public @NonNull List<LinkProperties> getStackedLinks() { if (mStackedLinks.isEmpty()) { return Collections.EMPTY_LIST; } List<LinkProperties> stacked = new ArrayList<LinkProperties>(); for (LinkProperties link : mStackedLinks.values()) { stacked.add(new LinkProperties(link)); Loading
core/java/com/android/internal/net/NetworkStatsFactory.java +66 −4 Original line number Diff line number Diff line Loading @@ -25,17 +25,20 @@ import static com.android.server.NetworkManagementSocketTagger.kernelToTag; import android.net.NetworkStats; import android.os.StrictMode; import android.os.SystemClock; import android.util.ArrayMap; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.internal.util.ProcFileReader; import libcore.io.IoUtils; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.ProtocolException; import libcore.io.IoUtils; import java.util.Objects; /** * Creates {@link NetworkStats} instances by parsing various {@code /proc/} Loading @@ -54,6 +57,19 @@ public class NetworkStatsFactory { /** Path to {@code /proc/net/xt_qtaguid/stats}. */ private final File mStatsXtUid; @GuardedBy("sStackedIfaces") private static final ArrayMap<String, String> sStackedIfaces = new ArrayMap<>(); public static void noteStackedIface(String stackedIface, String baseIface) { synchronized (sStackedIfaces) { if (baseIface != null) { sStackedIfaces.put(stackedIface, baseIface); } else { sStackedIfaces.remove(stackedIface); } } } public NetworkStatsFactory() { this(new File("/proc/")); } Loading Loading @@ -171,8 +187,54 @@ public class NetworkStatsFactory { } public NetworkStats readNetworkStatsDetail(int limitUid, String[] limitIfaces, int limitTag, NetworkStats lastStats) throws IOException { NetworkStats lastStats) throws IOException { final NetworkStats stats = readNetworkStatsDetailInternal(limitUid, limitIfaces, limitTag, lastStats); synchronized (sStackedIfaces) { // Sigh, xt_qtaguid ends up double-counting tx traffic going through // clatd interfaces, so we need to subtract it here. final int size = sStackedIfaces.size(); for (int i = 0; i < size; i++) { final String stackedIface = sStackedIfaces.keyAt(i); final String baseIface = sStackedIfaces.valueAt(i); // Count up the tx traffic and subtract from root UID on the // base interface. NetworkStats.Entry adjust = new NetworkStats.Entry(baseIface, 0, 0, 0, 0L, 0L, 0L, 0L, 0L); NetworkStats.Entry entry = null; for (int j = 0; j < stats.size(); j++) { entry = stats.getValues(j, entry); if (Objects.equals(entry.iface, stackedIface)) { adjust.txBytes -= entry.txBytes; adjust.txPackets -= entry.txPackets; } } stats.combineValues(adjust); } } // Double sigh, all rx traffic on clat needs to be tweaked to // account for the dropped IPv6 header size post-unwrap. NetworkStats.Entry entry = null; for (int i = 0; i < stats.size(); i++) { entry = stats.getValues(i, entry); if (entry.iface != null && entry.iface.startsWith("clat")) { // Delta between IPv4 header (20b) and IPv6 header (40b) entry.rxBytes = entry.rxPackets * 20; entry.rxPackets = 0; entry.txBytes = 0; entry.txPackets = 0; stats.combineValues(entry); } } return stats; } private NetworkStats readNetworkStatsDetailInternal(int limitUid, String[] limitIfaces, int limitTag, NetworkStats lastStats) throws IOException { if (USE_NATIVE_PARSING) { final NetworkStats stats; if (lastStats != null) { Loading
services/core/java/com/android/server/ConnectivityService.java +18 −5 Original line number Diff line number Diff line Loading @@ -119,7 +119,9 @@ import android.util.Xml; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.app.IBatteryStats; import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.NetworkStatsFactory; import com.android.internal.net.VpnConfig; import com.android.internal.net.VpnProfile; import com.android.internal.telephony.DctConstants; Loading Loading @@ -4476,12 +4478,23 @@ public class ConnectivityService extends IConnectivityManager.Stub { // TODO - read the tcp buffer size config string from somewhere // updateNetworkSettings(); } // notify battery stats service about this network // Notify battery stats service about this network, both the normal // interface and any stacked links. try { BatteryStatsService.getService().noteNetworkInterfaceType( newNetwork.linkProperties.getInterfaceName(), newNetwork.networkInfo.getType()); } catch (RemoteException e) { } final IBatteryStats bs = BatteryStatsService.getService(); final int type = newNetwork.networkInfo.getType(); final String baseIface = newNetwork.linkProperties.getInterfaceName(); bs.noteNetworkInterfaceType(baseIface, type); for (LinkProperties stacked : newNetwork.linkProperties.getStackedLinks()) { final String stackedIface = stacked.getInterfaceName(); bs.noteNetworkInterfaceType(stackedIface, type); NetworkStatsFactory.noteStackedIface(stackedIface, baseIface); } } catch (RemoteException ignored) { } notifyNetworkCallbacks(newNetwork, ConnectivityManager.CALLBACK_AVAILABLE); } else { if (DBG && newNetwork.networkRequests.size() != 0) { Loading
services/core/java/com/android/server/net/NetworkPolicyManagerService.java +31 −19 Original line number Diff line number Diff line Loading @@ -38,8 +38,8 @@ import static android.net.NetworkPolicy.LIMIT_DISABLED; import static android.net.NetworkPolicy.SNOOZE_NEVER; import static android.net.NetworkPolicy.WARNING_DISABLED; import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE; import static android.net.NetworkPolicyManager.POLICY_NONE; import static android.net.NetworkPolicyManager.POLICY_ALLOW_BACKGROUND_BATTERY_SAVE; import static android.net.NetworkPolicyManager.POLICY_NONE; import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; Loading Loading @@ -96,6 +96,7 @@ import android.net.INetworkManagementEventObserver; import android.net.INetworkPolicyListener; import android.net.INetworkPolicyManager; import android.net.INetworkStatsService; import android.net.LinkProperties; import android.net.NetworkIdentity; import android.net.NetworkInfo; import android.net.NetworkPolicy; Loading Loading @@ -127,6 +128,7 @@ import android.util.ArraySet; import android.util.AtomicFile; import android.util.Log; import android.util.NtpTrustedTime; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; Loading @@ -142,6 +144,8 @@ import com.android.server.LocalServices; import com.android.server.SystemConfig; import com.google.android.collect.Lists; import libcore.io.IoUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; Loading @@ -158,8 +162,6 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; import libcore.io.IoUtils; /** * Service that maintains low-level network policy rules, using * {@link NetworkStatsService} statistics to drive those rules. Loading Loading @@ -1049,36 +1051,44 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // use over those networks can have a cost associated with it). final boolean powerSave = mRestrictPower && !mRestrictBackground; // first, derive identity for all connected networks, which can be used // to match against templates. final ArrayMap<NetworkIdentity, String> networks = new ArrayMap<NetworkIdentity, String>(states.length); // First, generate identities of all connected networks so we can // quickly compare them against all defined policies below. final ArrayList<Pair<String, NetworkIdentity>> connIdents = new ArrayList<>(states.length); final ArraySet<String> connIfaces = new ArraySet<String>(states.length); for (NetworkState state : states) { // stash identity and iface away for later use if (state.networkInfo.isConnected()) { final String iface = state.linkProperties.getInterfaceName(); final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); networks.put(ident, iface); final String baseIface = state.linkProperties.getInterfaceName(); connIdents.add(Pair.create(baseIface, ident)); if (powerSave) { connIfaces.add(iface); connIfaces.add(baseIface); } // Stacked interfaces are considered to have same identity as // their parent network. final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks(); for (LinkProperties stackedLink : stackedLinks) { final String stackedIface = stackedLink.getInterfaceName(); connIdents.add(Pair.create(stackedIface, ident)); if (powerSave) { connIfaces.add(stackedIface); } } } } // build list of rules and ifaces to enforce them against // Apply policies against all connected interfaces found above mNetworkRules.clear(); final ArrayList<String> ifaceList = Lists.newArrayList(); for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) { final NetworkPolicy policy = mNetworkPolicy.valueAt(i); // collect all active ifaces that match this template ifaceList.clear(); for (int j = networks.size()-1; j >= 0; j--) { final NetworkIdentity ident = networks.keyAt(j); if (policy.template.matches(ident)) { final String iface = networks.valueAt(j); ifaceList.add(iface); for (int j = connIdents.size() - 1; j >= 0; j--) { final Pair<String, NetworkIdentity> ident = connIdents.get(j); if (policy.template.matches(ident.second)) { ifaceList.add(ident.first); } } Loading Loading @@ -1787,6 +1797,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } fout.decreaseIndent(); fout.print("Metered ifaces: "); fout.println(String.valueOf(mMeteredIfaces)); fout.println("Policy for UIDs:"); fout.increaseIndent(); int size = mUidPolicy.size(); Loading
services/core/java/com/android/server/net/NetworkStatsService.java +58 −27 Original line number Diff line number Diff line Loading @@ -62,8 +62,6 @@ 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.ArrayUtils.appendElement; import static com.android.internal.util.ArrayUtils.contains; import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT; import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats; Loading Loading @@ -107,6 +105,8 @@ import android.provider.Settings; import android.provider.Settings.Global; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.util.ArrayMap; import android.util.ArraySet; import android.util.EventLog; import android.util.Log; import android.util.MathUtils; Loading @@ -121,14 +121,12 @@ import com.android.internal.util.FileRotator; import com.android.internal.util.IndentingPrintWriter; import com.android.server.EventLogTags; import com.android.server.connectivity.Tethering; import com.google.android.collect.Maps; import java.io.File; import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; Loading Loading @@ -215,7 +213,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private final Object mStatsLock = new Object(); /** Set of currently active ifaces. */ private HashMap<String, NetworkIdentitySet> mActiveIfaces = Maps.newHashMap(); private final ArrayMap<String, NetworkIdentitySet> mActiveIfaces = new ArrayMap<>(); /** Set of currently active ifaces for UID stats. */ private final ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces = new ArrayMap<>(); /** Current default active iface. */ private String mActiveIface; /** Set of any ifaces associated with mobile networks since boot. */ Loading Loading @@ -883,30 +883,52 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mActiveIface = activeLink != null ? activeLink.getInterfaceName() : null; // rebuild active interfaces based on connected networks // Rebuild active interfaces based on connected networks mActiveIfaces.clear(); mActiveUidIfaces.clear(); final ArraySet<String> mobileIfaces = new ArraySet<>(); for (NetworkState state : states) { if (state.networkInfo.isConnected()) { // collect networks under their parent interfaces final String iface = state.linkProperties.getInterfaceName(); final boolean isMobile = isNetworkTypeMobile(state.networkInfo.getType()); final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); NetworkIdentitySet ident = mActiveIfaces.get(iface); if (ident == null) { ident = new NetworkIdentitySet(); mActiveIfaces.put(iface, ident); // Traffic occurring on the base interface is always counted for // both total usage and UID details. final String baseIface = state.linkProperties.getInterfaceName(); findOrCreateNetworkIdentitySet(mActiveIfaces, baseIface).add(ident); findOrCreateNetworkIdentitySet(mActiveUidIfaces, baseIface).add(ident); if (isMobile) { mobileIfaces.add(baseIface); } ident.add(NetworkIdentity.buildNetworkIdentity(mContext, state)); // remember any ifaces associated with mobile networks if (isNetworkTypeMobile(state.networkInfo.getType()) && iface != null) { if (!contains(mMobileIfaces, iface)) { mMobileIfaces = appendElement(String.class, mMobileIfaces, iface); // Traffic occurring on stacked interfaces is usually clatd, // which is already accounted against its final egress interface // by the kernel. Thus, we only need to collect stacked // interface stats at the UID level. final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks(); for (LinkProperties stackedLink : stackedLinks) { final String stackedIface = stackedLink.getInterfaceName(); findOrCreateNetworkIdentitySet(mActiveUidIfaces, stackedIface).add(ident); if (isMobile) { mobileIfaces.add(stackedIface); } } } } mobileIfaces.remove(null); mMobileIfaces = mobileIfaces.toArray(new String[mobileIfaces.size()]); } private static <K> NetworkIdentitySet findOrCreateNetworkIdentitySet( ArrayMap<K, NetworkIdentitySet> map, K key) { NetworkIdentitySet ident = map.get(key); if (ident == null) { ident = new NetworkIdentitySet(); map.put(key, ident); } return ident; } /** Loading @@ -926,8 +948,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime); mXtRecorder.recordSnapshotLocked(xtSnapshot, mActiveIfaces, currentTime); mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime); mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime); mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime); mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime); } catch (IllegalStateException e) { Slog.w(TAG, "problem reading network stats: " + e); Loading Loading @@ -980,8 +1002,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime); mXtRecorder.recordSnapshotLocked(xtSnapshot, mActiveIfaces, currentTime); mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime); mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime); mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime); mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime); } catch (IllegalStateException e) { Log.wtf(TAG, "problem reading network stats", e); Loading Loading @@ -1136,10 +1158,19 @@ public class NetworkStatsService extends INetworkStatsService.Stub { pw.println("Active interfaces:"); pw.increaseIndent(); for (String iface : mActiveIfaces.keySet()) { final NetworkIdentitySet ident = mActiveIfaces.get(iface); pw.print("iface="); pw.print(iface); pw.print(" ident="); pw.println(ident.toString()); for (int i = 0; i < mActiveIfaces.size(); i++) { pw.printPair("iface", mActiveIfaces.keyAt(i)); pw.printPair("ident", mActiveIfaces.valueAt(i)); pw.println(); } pw.decreaseIndent(); pw.println("Active UID interfaces:"); pw.increaseIndent(); for (int i = 0; i < mActiveUidIfaces.size(); i++) { pw.printPair("iface", mActiveUidIfaces.keyAt(i)); pw.printPair("ident", mActiveUidIfaces.valueAt(i)); pw.println(); } pw.decreaseIndent(); Loading