diff options
Diffstat (limited to 'services/java/com/android')
-rw-r--r-- | services/java/com/android/server/NetworkManagementService.java | 115 | ||||
-rw-r--r-- | services/java/com/android/server/ThrottleService.java | 3 | ||||
-rw-r--r-- | services/java/com/android/server/net/NetworkIdentity.java | 227 | ||||
-rw-r--r-- | services/java/com/android/server/net/NetworkIdentitySet.java (renamed from services/java/com/android/server/net/InterfaceIdentity.java) | 49 | ||||
-rw-r--r-- | services/java/com/android/server/net/NetworkPolicyManagerService.java | 60 | ||||
-rw-r--r-- | services/java/com/android/server/net/NetworkStatsService.java | 333 |
6 files changed, 356 insertions, 431 deletions
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java index bb0c671..d5bdd21 100644 --- a/services/java/com/android/server/NetworkManagementService.java +++ b/services/java/com/android/server/NetworkManagementService.java @@ -16,6 +16,10 @@ package com.android.server; +import static android.net.NetworkStats.IFACE_ALL; +import static android.net.NetworkStats.TAG_NONE; +import static android.net.NetworkStats.UID_ALL; + import android.content.Context; import android.content.pm.PackageManager; import android.net.INetworkManagementEventObserver; @@ -37,6 +41,7 @@ import java.io.BufferedReader; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; +import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.Inet4Address; @@ -59,8 +64,9 @@ class NetworkManagementService extends INetworkManagementService.Stub { private static final int ADD = 1; private static final int REMOVE = 2; - /** Base path to UID-granularity network statistics. */ - private static final File PATH_PROC_UID_STAT = new File("/proc/uid_stat"); + @Deprecated + private static final File STATS_UIDSTAT = new File("/proc/uid_stat"); + private static final File STATS_NETFILTER = new File("/proc/net/xt_qtaguid/stats"); class NetdResponseCode { public static final int InterfaceListResult = 110; @@ -899,7 +905,7 @@ class NetworkManagementService extends INetworkManagementService.Stub { for (String iface : ifaces) { final long rx = getInterfaceCounter(iface, true); final long tx = getInterfaceCounter(iface, false); - stats.addEntry(iface, NetworkStats.UID_ALL, rx, tx); + stats.addEntry(iface, UID_ALL, TAG_NONE, rx, tx); } return stats; @@ -910,16 +916,11 @@ class NetworkManagementService extends INetworkManagementService.Stub { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); - final String[] knownUids = PATH_PROC_UID_STAT.list(); - final NetworkStats stats = new NetworkStats( - SystemClock.elapsedRealtime(), knownUids.length); - - for (String uid : knownUids) { - final int uidInt = Integer.parseInt(uid); - collectNetworkStatsDetail(stats, uidInt); + if (STATS_NETFILTER.exists()) { + return getNetworkStatsDetailNetfilter(UID_ALL); + } else { + return getNetworkStatsDetailUidstat(UID_ALL); } - - return stats; } @Override @@ -929,19 +930,89 @@ class NetworkManagementService extends INetworkManagementService.Stub { android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); } - final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1); - collectNetworkStatsDetail(stats, uid); + if (STATS_NETFILTER.exists()) { + return getNetworkStatsDetailNetfilter(uid); + } else { + return getNetworkStatsDetailUidstat(uid); + } + } + + /** + * Build {@link NetworkStats} with detailed UID statistics. + */ + private NetworkStats getNetworkStatsDetailNetfilter(int limitUid) { + final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 24); + + BufferedReader reader = null; + try { + reader = new BufferedReader(new FileReader(STATS_NETFILTER)); + + // assumes format from kernel: + // idx iface acct_tag_hex uid_tag_int rx_bytes tx_bytes + + // skip first line, which is legend + String line = reader.readLine(); + while ((line = reader.readLine()) != null) { + final StringTokenizer t = new StringTokenizer(line); + + final String idx = t.nextToken(); + final String iface = t.nextToken(); + + try { + // TODO: kernel currently emits tag in upper half of long; + // eventually switch to directly using int. + final int tag = (int) (Long.parseLong(t.nextToken().substring(2), 16) >> 32); + final int uid = Integer.parseInt(t.nextToken()); + final long rx = Long.parseLong(t.nextToken()); + final long tx = Long.parseLong(t.nextToken()); + + if (limitUid == UID_ALL || limitUid == uid) { + stats.addEntry(iface, uid, tag, rx, tx); + if (tag != TAG_NONE) { + // proc also counts tagged data in generic tag, so + // we subtract it here to avoid double-counting. + stats.combineEntry(iface, uid, TAG_NONE, -rx, -tx); + } + } + } catch (NumberFormatException e) { + Slog.w(TAG, "problem parsing stats for idx " + idx + ": " + e); + } + } + } catch (IOException e) { + Slog.w(TAG, "problem parsing stats: " + e); + } finally { + IoUtils.closeQuietly(reader); + } + return stats; } - private void collectNetworkStatsDetail(NetworkStats stats, int uid) { - // TODO: kernel module will provide interface-level stats in future - // TODO: migrate these stats to come across netd in bulk, instead of all - // these individual file reads. - final File uidPath = new File(PATH_PROC_UID_STAT, Integer.toString(uid)); - final long rx = readSingleLongFromFile(new File(uidPath, "tcp_rcv")); - final long tx = readSingleLongFromFile(new File(uidPath, "tcp_snd")); - stats.addEntry(NetworkStats.IFACE_ALL, uid, rx, tx); + /** + * Build {@link NetworkStats} with detailed UID statistics. + * + * @deprecated since this uses older "uid_stat" data, and doesn't provide + * tag-level granularity or additional variables. + */ + @Deprecated + private NetworkStats getNetworkStatsDetailUidstat(int limitUid) { + final String[] knownUids; + if (limitUid == UID_ALL) { + knownUids = STATS_UIDSTAT.list(); + } else { + knownUids = new String[] { String.valueOf(limitUid) }; + } + + final NetworkStats stats = new NetworkStats( + SystemClock.elapsedRealtime(), knownUids.length); + for (String uid : knownUids) { + final int uidInt = Integer.parseInt(uid); + final File uidPath = new File(STATS_UIDSTAT, uid); + final long rx = readSingleLongFromFile(new File(uidPath, "tcp_rcv")); + final long tx = readSingleLongFromFile(new File(uidPath, "tcp_snd")); + stats.addEntry(IFACE_ALL, uidInt, TAG_NONE, rx, tx); + } + + return stats; } public void setInterfaceThrottle(String iface, int rxKbps, int txKbps) { diff --git a/services/java/com/android/server/ThrottleService.java b/services/java/com/android/server/ThrottleService.java index 510ff62..7266d7d 100644 --- a/services/java/com/android/server/ThrottleService.java +++ b/services/java/com/android/server/ThrottleService.java @@ -533,7 +533,8 @@ public class ThrottleService extends IThrottleManager.Stub { long incWrite = 0; try { final NetworkStats stats = mNMService.getNetworkStatsSummary(); - final int index = stats.findIndex(mIface, NetworkStats.UID_ALL); + final int index = stats.findIndex( + mIface, NetworkStats.UID_ALL, NetworkStats.TAG_NONE); if (index != -1) { incRead = stats.rx[index] - mLastRead; diff --git a/services/java/com/android/server/net/NetworkIdentity.java b/services/java/com/android/server/net/NetworkIdentity.java deleted file mode 100644 index 4a207f7..0000000 --- a/services/java/com/android/server/net/NetworkIdentity.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.net; - -import static android.net.ConnectivityManager.TYPE_WIFI; -import static android.net.ConnectivityManager.TYPE_WIMAX; -import static android.net.ConnectivityManager.isNetworkTypeMobile; -import static android.net.TrafficStats.TEMPLATE_MOBILE_3G_LOWER; -import static android.net.TrafficStats.TEMPLATE_MOBILE_4G; -import static android.net.TrafficStats.TEMPLATE_MOBILE_ALL; -import static android.net.TrafficStats.TEMPLATE_WIFI; -import static android.telephony.TelephonyManager.NETWORK_CLASS_2_G; -import static android.telephony.TelephonyManager.NETWORK_CLASS_3_G; -import static android.telephony.TelephonyManager.NETWORK_CLASS_4_G; -import static android.telephony.TelephonyManager.NETWORK_CLASS_UNKNOWN; -import static android.telephony.TelephonyManager.getNetworkClass; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.net.NetworkState; -import android.telephony.TelephonyManager; - -import com.android.internal.util.Objects; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.net.ProtocolException; - -/** - * Identity of a {@link NetworkInfo}, defined by network type and billing - * relationship (such as IMSI). - * - * @hide - */ -public class NetworkIdentity { - private static final int VERSION_CURRENT = 1; - - public final int type; - public final int subType; - public final String subscriberId; - - public NetworkIdentity(int type, int subType, String subscriberId) { - this.type = type; - this.subType = subType; - this.subscriberId = subscriberId; - } - - public NetworkIdentity(DataInputStream in) throws IOException { - final int version = in.readInt(); - switch (version) { - case VERSION_CURRENT: { - type = in.readInt(); - subType = in.readInt(); - subscriberId = readOptionalString(in); - break; - } - default: { - throw new ProtocolException("unexpected version: " + version); - } - } - } - - public void writeToStream(DataOutputStream out) throws IOException { - out.writeInt(VERSION_CURRENT); - out.writeInt(type); - out.writeInt(subType); - writeOptionalString(out, subscriberId); - } - - @Override - public int hashCode() { - return Objects.hashCode(type, subType, subscriberId); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof NetworkIdentity) { - final NetworkIdentity ident = (NetworkIdentity) obj; - return type == ident.type && subType == ident.subType - && Objects.equal(subscriberId, ident.subscriberId); - } - return false; - } - - @Override - public String toString() { - final String typeName = ConnectivityManager.getNetworkTypeName(type); - final String subTypeName; - if (ConnectivityManager.isNetworkTypeMobile(type)) { - subTypeName = TelephonyManager.getNetworkTypeName(subType); - } else { - subTypeName = Integer.toString(subType); - } - - return "[type=" + typeName + ", subType=" + subTypeName + ", subId=" + subscriberId + "]"; - } - - /** - * Test if this network matches the given template and IMEI. - */ - public boolean matchesTemplate(int networkTemplate, String subscriberId) { - switch (networkTemplate) { - case TEMPLATE_MOBILE_ALL: - return matchesMobile(subscriberId); - case TEMPLATE_MOBILE_3G_LOWER: - return matchesMobile3gLower(subscriberId); - case TEMPLATE_MOBILE_4G: - return matchesMobile4g(subscriberId); - case TEMPLATE_WIFI: - return matchesWifi(); - default: - throw new IllegalArgumentException("unknown network template"); - } - } - - /** - * Check if mobile network with matching IMEI. Also matches - * {@link #TYPE_WIMAX}. - */ - private boolean matchesMobile(String subscriberId) { - if (isNetworkTypeMobile(type) && Objects.equal(this.subscriberId, subscriberId)) { - return true; - } else if (type == TYPE_WIMAX) { - return true; - } - return false; - } - - /** - * Check if mobile network classified 3G or lower with matching IMEI. - */ - private boolean matchesMobile3gLower(String subscriberId) { - if (isNetworkTypeMobile(type) - && Objects.equal(this.subscriberId, subscriberId)) { - switch (getNetworkClass(subType)) { - case NETWORK_CLASS_UNKNOWN: - case NETWORK_CLASS_2_G: - case NETWORK_CLASS_3_G: - return true; - } - } - return false; - } - - /** - * Check if mobile network classified 4G with matching IMEI. Also matches - * {@link #TYPE_WIMAX}. - */ - private boolean matchesMobile4g(String subscriberId) { - if (isNetworkTypeMobile(type) - && Objects.equal(this.subscriberId, subscriberId)) { - switch (getNetworkClass(subType)) { - case NETWORK_CLASS_4_G: - return true; - } - } else if (type == TYPE_WIMAX) { - return true; - } - return false; - } - - /** - * Check if matches Wi-Fi network template. - */ - private boolean matchesWifi() { - if (type == TYPE_WIFI) { - return true; - } - return false; - } - - /** - * Build a {@link NetworkIdentity} from the given {@link NetworkState}, - * assuming that any mobile networks are using the current IMSI. - */ - public static NetworkIdentity buildNetworkIdentity(Context context, NetworkState state) { - final int type = state.networkInfo.getType(); - final int subType = state.networkInfo.getSubtype(); - - // TODO: consider moving subscriberId over to LinkCapabilities, so it - // comes from an authoritative source. - - final String subscriberId; - if (isNetworkTypeMobile(type)) { - final TelephonyManager telephony = (TelephonyManager) context.getSystemService( - Context.TELEPHONY_SERVICE); - subscriberId = telephony.getSubscriberId(); - } else { - subscriberId = null; - } - return new NetworkIdentity(type, subType, subscriberId); - } - - private static void writeOptionalString(DataOutputStream out, String value) throws IOException { - if (value != null) { - out.writeByte(1); - out.writeUTF(value); - } else { - out.writeByte(0); - } - } - - private static String readOptionalString(DataInputStream in) throws IOException { - if (in.readByte() != 0) { - return in.readUTF(); - } else { - return null; - } - } - -} diff --git a/services/java/com/android/server/net/InterfaceIdentity.java b/services/java/com/android/server/net/NetworkIdentitySet.java index ff86581..757d3bc 100644 --- a/services/java/com/android/server/net/InterfaceIdentity.java +++ b/services/java/com/android/server/net/NetworkIdentitySet.java @@ -16,6 +16,8 @@ package com.android.server.net; +import android.net.NetworkIdentity; + import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; @@ -28,19 +30,23 @@ import java.util.HashSet; * * @hide */ -public class InterfaceIdentity extends HashSet<NetworkIdentity> { - private static final int VERSION_CURRENT = 1; +public class NetworkIdentitySet extends HashSet<NetworkIdentity> { + private static final int VERSION_INIT = 1; - public InterfaceIdentity() { + public NetworkIdentitySet() { } - public InterfaceIdentity(DataInputStream in) throws IOException { + public NetworkIdentitySet(DataInputStream in) throws IOException { final int version = in.readInt(); switch (version) { - case VERSION_CURRENT: { + case VERSION_INIT: { final int size = in.readInt(); for (int i = 0; i < size; i++) { - add(new NetworkIdentity(in)); + final int ignoredVersion = in.readInt(); + final int type = in.readInt(); + final int subType = in.readInt(); + final String subscriberId = readOptionalString(in); + add(new NetworkIdentity(type, subType, subscriberId)); } break; } @@ -51,23 +57,30 @@ public class InterfaceIdentity extends HashSet<NetworkIdentity> { } public void writeToStream(DataOutputStream out) throws IOException { - out.writeInt(VERSION_CURRENT); + out.writeInt(VERSION_INIT); out.writeInt(size()); for (NetworkIdentity ident : this) { - ident.writeToStream(out); + out.writeInt(VERSION_INIT); + out.writeInt(ident.getType()); + out.writeInt(ident.getSubType()); + writeOptionalString(out, ident.getSubscriberId()); } } - /** - * Test if any {@link NetworkIdentity} on this interface matches the given - * template and IMEI. - */ - public boolean matchesTemplate(int networkTemplate, String subscriberId) { - for (NetworkIdentity ident : this) { - if (ident.matchesTemplate(networkTemplate, subscriberId)) { - return true; - } + private static void writeOptionalString(DataOutputStream out, String value) throws IOException { + if (value != null) { + out.writeByte(1); + out.writeUTF(value); + } else { + out.writeByte(0); + } + } + + private static String readOptionalString(DataInputStream in) throws IOException { + if (in.readByte() != 0) { + return in.readUTF(); + } else { + return null; } - return false; } } diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java index 43f3c63..ada9ba4 100644 --- a/services/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java @@ -23,6 +23,7 @@ import static android.Manifest.permission.MANAGE_NETWORK_POLICY; import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY; import static android.Manifest.permission.READ_PHONE_STATE; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; +import static android.net.ConnectivityManager.TYPE_MOBILE; import static android.net.NetworkPolicy.LIMIT_DISABLED; import static android.net.NetworkPolicy.WARNING_DISABLED; import static android.net.NetworkPolicyManager.ACTION_DATA_USAGE_LIMIT; @@ -36,10 +37,9 @@ import static android.net.NetworkPolicyManager.computeLastCycleBoundary; import static android.net.NetworkPolicyManager.dumpPolicy; import static android.net.NetworkPolicyManager.dumpRules; import static android.net.NetworkPolicyManager.isUidValidForPolicy; -import static android.net.TrafficStats.TEMPLATE_MOBILE_3G_LOWER; -import static android.net.TrafficStats.TEMPLATE_MOBILE_4G; -import static android.net.TrafficStats.TEMPLATE_MOBILE_ALL; -import static android.net.TrafficStats.isNetworkTemplateMobile; +import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER; +import static android.net.NetworkTemplate.MATCH_MOBILE_4G; +import static android.net.NetworkTemplate.MATCH_MOBILE_ALL; import static android.text.format.DateUtils.DAY_IN_MILLIS; import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED; @@ -61,9 +61,11 @@ import android.net.IConnectivityManager; import android.net.INetworkPolicyListener; import android.net.INetworkPolicyManager; import android.net.INetworkStatsService; +import android.net.NetworkIdentity; import android.net.NetworkPolicy; import android.net.NetworkState; import android.net.NetworkStats; +import android.net.NetworkTemplate; import android.os.Environment; import android.os.Handler; import android.os.HandlerThread; @@ -84,7 +86,6 @@ import android.util.Xml; import com.android.internal.R; import com.android.internal.os.AtomicFile; import com.android.internal.util.FastXmlSerializer; -import com.android.internal.util.Objects; import com.google.android.collect.Lists; import com.google.android.collect.Maps; import com.google.android.collect.Sets; @@ -353,10 +354,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final long total; try { final NetworkStats stats = mNetworkStats.getSummaryForNetwork( - start, end, policy.networkTemplate, policy.subscriberId); + policy.template, start, end); total = stats.rx[0] + stats.tx[0]; } catch (RemoteException e) { - Slog.w(TAG, "problem reading summary for template " + policy.networkTemplate); + Slog.w(TAG, "problem reading summary for template " + policy.template); continue; } @@ -380,8 +381,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { * notification of a specific type, like {@link #TYPE_LIMIT}. */ private String buildNotificationTag(NetworkPolicy policy, int type) { - // TODO: consider splicing subscriberId hash into mix - return TAG + ":" + policy.networkTemplate + ":" + type; + return TAG + ":" + policy.template.hashCode() + ":" + type; } /** @@ -408,7 +408,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final Intent intent = new Intent(ACTION_DATA_USAGE_WARNING); intent.addCategory(Intent.CATEGORY_DEFAULT); - intent.putExtra(EXTRA_NETWORK_TEMPLATE, policy.networkTemplate); + intent.putExtra(EXTRA_NETWORK_TEMPLATE, policy.template.getMatchRule()); builder.setContentIntent(PendingIntent.getActivity( mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); break; @@ -416,11 +416,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { case TYPE_LIMIT: { final String title; final String body = res.getString(R.string.data_usage_limit_body); - switch (policy.networkTemplate) { - case TEMPLATE_MOBILE_3G_LOWER: + switch (policy.template.getMatchRule()) { + case MATCH_MOBILE_3G_LOWER: title = res.getString(R.string.data_usage_3g_limit_title); break; - case TEMPLATE_MOBILE_4G: + case MATCH_MOBILE_4G: title = res.getString(R.string.data_usage_4g_limit_title); break; default: @@ -435,7 +435,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final Intent intent = new Intent(ACTION_DATA_USAGE_LIMIT); intent.addCategory(Intent.CATEGORY_DEFAULT); - intent.putExtra(EXTRA_NETWORK_TEMPLATE, policy.networkTemplate); + intent.putExtra(EXTRA_NETWORK_TEMPLATE, policy.template.getMatchRule()); builder.setContentIntent(PendingIntent.getActivity( mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); break; @@ -521,7 +521,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // collect all active ifaces that match this template ifaceList.clear(); for (NetworkIdentity ident : networks.keySet()) { - if (ident.matchesTemplate(policy.networkTemplate, policy.subscriberId)) { + if (policy.template.matches(ident)) { final String iface = networks.get(ident); ifaceList.add(iface); } @@ -554,11 +554,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final NetworkStats stats; final long total; try { - stats = mNetworkStats.getSummaryForNetwork( - start, end, policy.networkTemplate, policy.subscriberId); + stats = mNetworkStats.getSummaryForNetwork(policy.template, start, end); total = stats.rx[0] + stats.tx[0]; } catch (RemoteException e) { - Slog.w(TAG, "problem reading summary for template " + policy.networkTemplate); + Slog.w(TAG, "problem reading summary for template " + policy.template); continue; } @@ -603,12 +602,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private void ensureActiveMobilePolicyLocked() { if (LOGV) Slog.v(TAG, "ensureActiveMobilePolicyLocked()"); final String subscriberId = getActiveSubscriberId(); + final NetworkIdentity probeIdent = new NetworkIdentity( + TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId); // examine to see if any policy is defined for active mobile boolean mobileDefined = false; for (NetworkPolicy policy : mNetworkPolicy) { - if (isNetworkTemplateMobile(policy.networkTemplate) - && Objects.equal(subscriberId, policy.subscriberId)) { + if (policy.template.matches(probeIdent)) { mobileDefined = true; } } @@ -624,8 +624,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { time.setToNow(); final int cycleDay = time.monthDay; - mNetworkPolicy.add(new NetworkPolicy( - TEMPLATE_MOBILE_ALL, subscriberId, cycleDay, 4 * GB_IN_BYTES, LIMIT_DISABLED)); + final NetworkTemplate template = new NetworkTemplate(MATCH_MOBILE_ALL, subscriberId); + mNetworkPolicy.add( + new NetworkPolicy(template, cycleDay, 4 * GB_IN_BYTES, LIMIT_DISABLED)); writePolicyLocked(); } } @@ -658,8 +659,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final long warningBytes = readLongAttribute(in, ATTR_WARNING_BYTES); final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES); - mNetworkPolicy.add(new NetworkPolicy( - networkTemplate, subscriberId, cycleDay, warningBytes, limitBytes)); + final NetworkTemplate template = new NetworkTemplate( + networkTemplate, subscriberId); + mNetworkPolicy.add( + new NetworkPolicy(template, cycleDay, warningBytes, limitBytes)); } else if (TAG_UID_POLICY.equals(tag)) { final int uid = readIntAttribute(in, ATTR_UID); @@ -701,10 +704,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // write all known network policies for (NetworkPolicy policy : mNetworkPolicy) { + final NetworkTemplate template = policy.template; + out.startTag(null, TAG_NETWORK_POLICY); - writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, policy.networkTemplate); - if (policy.subscriberId != null) { - out.attribute(null, ATTR_SUBSCRIBER_ID, policy.subscriberId); + writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, template.getMatchRule()); + final String subscriberId = template.getSubscriberId(); + if (subscriberId != null) { + out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId); } writeIntAttribute(out, ATTR_CYCLE_DAY, policy.cycleDay); writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes); diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java index 0a84bc7..54a806a 100644 --- a/services/java/com/android/server/net/NetworkStatsService.java +++ b/services/java/com/android/server/net/NetworkStatsService.java @@ -22,6 +22,7 @@ import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY; import static android.Manifest.permission.SHUTDOWN; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.NetworkStats.IFACE_ALL; +import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.UID_ALL; import static android.provider.Settings.Secure.NETSTATS_NETWORK_BUCKET_DURATION; import static android.provider.Settings.Secure.NETSTATS_NETWORK_MAX_HISTORY; @@ -45,10 +46,12 @@ import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.net.IConnectivityManager; import android.net.INetworkStatsService; +import android.net.NetworkIdentity; import android.net.NetworkInfo; import android.net.NetworkState; import android.net.NetworkStats; import android.net.NetworkStatsHistory; +import android.net.NetworkTemplate; import android.os.Environment; import android.os.Handler; import android.os.HandlerThread; @@ -63,8 +66,8 @@ import android.util.SparseArray; import android.util.TrustedTime; import com.android.internal.os.AtomicFile; -import com.google.android.collect.Lists; import com.google.android.collect.Maps; +import com.google.android.collect.Sets; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -76,9 +79,9 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.net.ProtocolException; -import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import libcore.io.IoUtils; @@ -93,7 +96,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { /** File header magic number: "ANET" */ private static final int FILE_MAGIC = 0x414E4554; - private static final int VERSION_CURRENT = 1; + private static final int VERSION_NETWORK_INIT = 1; + private static final int VERSION_UID_INIT = 1; + private static final int VERSION_UID_WITH_IDENT = 2; private final Context mContext; private final INetworkManagementService mNetworkManager; @@ -112,6 +117,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private PendingIntent mPollIntent; // TODO: listen for kernel push events through netd instead of polling + // TODO: watch for UID uninstall, and transfer stats into single bucket private static final long KB_IN_BYTES = 1024; private static final long MB_IN_BYTES = 1024 * KB_IN_BYTES; @@ -132,13 +138,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private final Object mStatsLock = new Object(); - /** Set of active ifaces during this boot. */ - private HashMap<String, InterfaceIdentity> mActiveIface = Maps.newHashMap(); - - /** Set of historical stats for known ifaces. */ - private HashMap<InterfaceIdentity, NetworkStatsHistory> mNetworkStats = Maps.newHashMap(); + /** Set of currently active ifaces. */ + private HashMap<String, NetworkIdentitySet> mActiveIfaces = Maps.newHashMap(); + /** Set of historical stats for known networks. */ + private HashMap<NetworkIdentitySet, NetworkStatsHistory> mNetworkStats = Maps.newHashMap(); /** Set of historical stats for known UIDs. */ - private SparseArray<NetworkStatsHistory> mUidStats = new SparseArray<NetworkStatsHistory>(); + private HashMap<NetworkIdentitySet, SparseArray<NetworkStatsHistory>> mUidStats = + Maps.newHashMap(); /** Flag if {@link #mUidStats} have been loaded from disk. */ private boolean mUidStatsLoaded = false; @@ -251,17 +257,16 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } @Override - public NetworkStatsHistory getHistoryForNetwork(int networkTemplate) { + public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template) { mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG); synchronized (mStatsLock) { // combine all interfaces that match template - final String subscriberId = getActiveSubscriberId(); final NetworkStatsHistory combined = new NetworkStatsHistory( mSettings.getNetworkBucketDuration(), estimateNetworkBuckets()); - for (InterfaceIdentity ident : mNetworkStats.keySet()) { - final NetworkStatsHistory history = mNetworkStats.get(ident); - if (ident.matchesTemplate(networkTemplate, subscriberId)) { + for (NetworkIdentitySet ident : mNetworkStats.keySet()) { + if (templateMatches(template, ident)) { + final NetworkStatsHistory history = mNetworkStats.get(ident); combined.recordEntireHistory(history); } } @@ -270,19 +275,29 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } @Override - public NetworkStatsHistory getHistoryForUid(int uid, int networkTemplate) { + public NetworkStatsHistory getHistoryForUid(NetworkTemplate template, int uid) { mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG); synchronized (mStatsLock) { - // TODO: combine based on template, if we store that granularity ensureUidStatsLoadedLocked(); - return mUidStats.get(uid); + + // combine all interfaces that match template + final NetworkStatsHistory combined = new NetworkStatsHistory( + mSettings.getUidBucketDuration(), estimateUidBuckets()); + for (NetworkIdentitySet ident : mUidStats.keySet()) { + if (templateMatches(template, ident)) { + final NetworkStatsHistory history = mUidStats.get(ident).get(uid); + if (history != null) { + combined.recordEntireHistory(history); + } + } + } + return combined; } } @Override - public NetworkStats getSummaryForNetwork( - long start, long end, int networkTemplate, String subscriberId) { + public NetworkStats getSummaryForNetwork(NetworkTemplate template, long start, long end) { mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG); synchronized (mStatsLock) { @@ -291,9 +306,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { long[] networkTotal = new long[2]; // combine total from all interfaces that match template - for (InterfaceIdentity ident : mNetworkStats.keySet()) { - final NetworkStatsHistory history = mNetworkStats.get(ident); - if (ident.matchesTemplate(networkTemplate, subscriberId)) { + for (NetworkIdentitySet ident : mNetworkStats.keySet()) { + if (templateMatches(template, ident)) { + final NetworkStatsHistory history = mNetworkStats.get(ident); networkTotal = history.getTotalData(start, end, networkTotal); rx += networkTotal[0]; tx += networkTotal[1]; @@ -301,30 +316,33 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } final NetworkStats stats = new NetworkStats(end - start, 1); - stats.addEntry(IFACE_ALL, UID_ALL, rx, tx); + stats.addEntry(IFACE_ALL, UID_ALL, TAG_NONE, rx, tx); return stats; } } @Override - public NetworkStats getSummaryForAllUid(long start, long end, int networkTemplate) { + public NetworkStats getSummaryForAllUid(NetworkTemplate template, long start, long end) { mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG); - // TODO: apply networktemplate once granular uid stats are stored. - synchronized (mStatsLock) { ensureUidStatsLoadedLocked(); - final int size = mUidStats.size(); - final NetworkStats stats = new NetworkStats(end - start, size); - + final NetworkStats stats = new NetworkStats(end - start, 24); long[] total = new long[2]; - for (int i = 0; i < size; i++) { - final int uid = mUidStats.keyAt(i); - final NetworkStatsHistory history = mUidStats.valueAt(i); - total = history.getTotalData(start, end, total); - stats.addEntry(IFACE_ALL, uid, total[0], total[1]); + + for (NetworkIdentitySet ident : mUidStats.keySet()) { + if (templateMatches(template, ident)) { + final SparseArray<NetworkStatsHistory> uidStats = mUidStats.get(ident); + for (int i = 0; i < uidStats.size(); i++) { + final int uid = uidStats.keyAt(i); + final NetworkStatsHistory history = uidStats.valueAt(i); + total = history.getTotalData(start, end, total); + stats.combineEntry(IFACE_ALL, uid, TAG_NONE, total[0], total[1]); + } + } } + return stats; } } @@ -352,7 +370,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // permission above. synchronized (mStatsLock) { // TODO: acquire wakelock while performing poll - performPollLocked(true); + performPollLocked(true, false); } } }; @@ -371,7 +389,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { * Inspect all current {@link NetworkState} to derive mapping from {@code * iface} to {@link NetworkStatsHistory}. When multiple {@link NetworkInfo} * are active on a single {@code iface}, they are combined under a single - * {@link InterfaceIdentity}. + * {@link NetworkIdentitySet}. */ private void updateIfacesLocked() { if (LOGV) Slog.v(TAG, "updateIfacesLocked()"); @@ -379,7 +397,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // take one last stats snapshot before updating iface mapping. this // isn't perfect, since the kernel may already be counting traffic from // the updated network. - performPollLocked(false); + performPollLocked(false, false); final NetworkState[] states; try { @@ -390,13 +408,19 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } // rebuild active interfaces based on connected networks - mActiveIface.clear(); + mActiveIfaces.clear(); for (NetworkState state : states) { if (state.networkInfo.isConnected()) { // collect networks under their parent interfaces final String iface = state.linkProperties.getInterfaceName(); - final InterfaceIdentity ident = findOrCreateInterfaceLocked(iface); + + NetworkIdentitySet ident = mActiveIfaces.get(iface); + if (ident == null) { + ident = new NetworkIdentitySet(); + mActiveIfaces.put(iface, ident); + } + ident.add(NetworkIdentity.buildNetworkIdentity(mContext, state)); } } @@ -409,7 +433,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { * @param detailedPoll Indicate if detailed UID stats should be collected * during this poll operation. */ - private void performPollLocked(boolean detailedPoll) { + private void performPollLocked(boolean detailedPoll, boolean forcePersist) { if (LOGV) Slog.v(TAG, "performPollLocked()"); // try refreshing time source when stale @@ -421,33 +445,33 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis(); - final NetworkStats networkStats; + final NetworkStats ifaceStats; final NetworkStats uidStats; try { - networkStats = mNetworkManager.getNetworkStatsSummary(); + ifaceStats = mNetworkManager.getNetworkStatsSummary(); uidStats = detailedPoll ? mNetworkManager.getNetworkStatsDetail() : null; } catch (RemoteException e) { Slog.w(TAG, "problem reading network stats"); return; } - performNetworkPollLocked(networkStats, currentTime); + performNetworkPollLocked(ifaceStats, currentTime); if (detailedPoll) { performUidPollLocked(uidStats, currentTime); } // decide if enough has changed to trigger persist - final NetworkStats persistDelta = computeStatsDelta(mLastNetworkPersist, networkStats); + final NetworkStats persistDelta = computeStatsDelta(mLastNetworkPersist, ifaceStats); final long persistThreshold = mSettings.getPersistThreshold(); for (String iface : persistDelta.getUniqueIfaces()) { - final int index = persistDelta.findIndex(iface, UID_ALL); - if (persistDelta.rx[index] > persistThreshold + final int index = persistDelta.findIndex(iface, UID_ALL, TAG_NONE); + if (forcePersist || persistDelta.rx[index] > persistThreshold || persistDelta.tx[index] > persistThreshold) { writeNetworkStatsLocked(); if (mUidStatsLoaded) { writeUidStatsLocked(); } - mLastNetworkPersist = networkStats; + mLastNetworkPersist = ifaceStats; break; } } @@ -462,23 +486,23 @@ public class NetworkStatsService extends INetworkStatsService.Stub { * Update {@link #mNetworkStats} historical usage. */ private void performNetworkPollLocked(NetworkStats networkStats, long currentTime) { - final ArrayList<String> unknownIface = Lists.newArrayList(); + final HashSet<String> unknownIface = Sets.newHashSet(); final NetworkStats delta = computeStatsDelta(mLastNetworkPoll, networkStats); final long timeStart = currentTime - delta.elapsedRealtime; final long maxHistory = mSettings.getNetworkMaxHistory(); - for (String iface : delta.getUniqueIfaces()) { - final InterfaceIdentity ident = mActiveIface.get(iface); + for (int i = 0; i < delta.size; i++) { + final String iface = delta.iface[i]; + final NetworkIdentitySet ident = mActiveIfaces.get(iface); if (ident == null) { unknownIface.add(iface); continue; } - final int index = delta.findIndex(iface, UID_ALL); - final long rx = delta.rx[index]; - final long tx = delta.tx[index]; + final long rx = delta.rx[i]; + final long tx = delta.tx[i]; - final NetworkStatsHistory history = findOrCreateNetworkLocked(ident); + final NetworkStatsHistory history = findOrCreateNetworkStatsLocked(ident); history.recordData(timeStart, currentTime, rx, tx); history.removeBucketsBefore(currentTime - maxHistory); } @@ -498,22 +522,30 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final NetworkStats delta = computeStatsDelta(mLastUidPoll, uidStats); final long timeStart = currentTime - delta.elapsedRealtime; final long maxHistory = mSettings.getUidMaxHistory(); - for (int uid : delta.getUniqueUids()) { - // TODO: traverse all ifaces once surfaced in stats - final int index = delta.findIndex(IFACE_ALL, uid); - if (index != -1) { - final long rx = delta.rx[index]; - final long tx = delta.tx[index]; - - final NetworkStatsHistory history = findOrCreateUidLocked(uid); - history.recordData(timeStart, currentTime, rx, tx); - history.removeBucketsBefore(currentTime - maxHistory); + + // NOTE: historical UID stats ignore tags, and simply records all stats + // entries into a single UID bucket. + + for (int i = 0; i < delta.size; i++) { + final String iface = delta.iface[i]; + final NetworkIdentitySet ident = mActiveIfaces.get(iface); + if (ident == null) { + continue; } + + final int uid = delta.uid[i]; + final long rx = delta.rx[i]; + final long tx = delta.tx[i]; + + final NetworkStatsHistory history = findOrCreateUidStatsLocked(ident, uid); + history.recordData(timeStart, currentTime, rx, tx); + history.removeBucketsBefore(currentTime - maxHistory); } + mLastUidPoll = uidStats; } - private NetworkStatsHistory findOrCreateNetworkLocked(InterfaceIdentity ident) { + private NetworkStatsHistory findOrCreateNetworkStatsLocked(NetworkIdentitySet ident) { final long bucketDuration = mSettings.getNetworkBucketDuration(); final NetworkStatsHistory existing = mNetworkStats.get(ident); @@ -535,9 +567,16 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } } - private NetworkStatsHistory findOrCreateUidLocked(int uid) { + private NetworkStatsHistory findOrCreateUidStatsLocked(NetworkIdentitySet ident, int uid) { + // find bucket for identity first, then find uid + SparseArray<NetworkStatsHistory> uidStats = mUidStats.get(ident); + if (uidStats == null) { + uidStats = new SparseArray<NetworkStatsHistory>(); + mUidStats.put(ident, uidStats); + } + final long bucketDuration = mSettings.getUidBucketDuration(); - final NetworkStatsHistory existing = mUidStats.get(uid); + final NetworkStatsHistory existing = uidStats.get(uid); // update when no existing, or when bucket duration changed NetworkStatsHistory updated = null; @@ -550,22 +589,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } if (updated != null) { - mUidStats.put(uid, updated); + uidStats.put(uid, updated); return updated; } else { return existing; } } - private InterfaceIdentity findOrCreateInterfaceLocked(String iface) { - InterfaceIdentity ident = mActiveIface.get(iface); - if (ident == null) { - ident = new InterfaceIdentity(); - mActiveIface.put(iface, ident); - } - return ident; - } - private void readNetworkStatsLocked() { if (LOGV) Slog.v(TAG, "readNetworkStatsLocked()"); @@ -585,15 +615,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final int version = in.readInt(); switch (version) { - case VERSION_CURRENT: { - // file format is pairs of interfaces and stats: - // network := size *(InterfaceIdentity NetworkStatsHistory) - + case VERSION_NETWORK_INIT: { + // network := size *(NetworkIdentitySet NetworkStatsHistory) final int size = in.readInt(); for (int i = 0; i < size; i++) { - final InterfaceIdentity ident = new InterfaceIdentity(in); + final NetworkIdentitySet ident = new NetworkIdentitySet(in); final NetworkStatsHistory history = new NetworkStatsHistory(in); - mNetworkStats.put(ident, history); } break; @@ -637,16 +664,29 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final int version = in.readInt(); switch (version) { - case VERSION_CURRENT: { - // file format is pairs of UIDs and stats: + case VERSION_UID_INIT: { // uid := size *(UID NetworkStatsHistory) - final int size = in.readInt(); - for (int i = 0; i < size; i++) { - final int uid = in.readInt(); - final NetworkStatsHistory history = new NetworkStatsHistory(in); - - mUidStats.put(uid, history); + // drop this data version, since we don't have a good + // mapping into NetworkIdentitySet. + break; + } + case VERSION_UID_WITH_IDENT: { + // uid := size *(NetworkIdentitySet size *(UID NetworkStatsHistory)) + final int ifaceSize = in.readInt(); + for (int i = 0; i < ifaceSize; i++) { + final NetworkIdentitySet ident = new NetworkIdentitySet(in); + + final int uidSize = in.readInt(); + final SparseArray<NetworkStatsHistory> uidStats = new SparseArray< + NetworkStatsHistory>(uidSize); + for (int j = 0; j < uidSize; j++) { + final int uid = in.readInt(); + final NetworkStatsHistory history = new NetworkStatsHistory(in); + uidStats.put(uid, history); + } + + mUidStats.put(ident, uidStats); } break; } @@ -674,10 +714,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final DataOutputStream out = new DataOutputStream(fos); out.writeInt(FILE_MAGIC); - out.writeInt(VERSION_CURRENT); + out.writeInt(VERSION_NETWORK_INIT); out.writeInt(mNetworkStats.size()); - for (InterfaceIdentity ident : mNetworkStats.keySet()) { + for (NetworkIdentitySet ident : mNetworkStats.keySet()) { final NetworkStatsHistory history = mNetworkStats.get(ident); ident.writeToStream(out); history.writeToStream(out); @@ -702,16 +742,21 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final DataOutputStream out = new DataOutputStream(fos); out.writeInt(FILE_MAGIC); - out.writeInt(VERSION_CURRENT); + out.writeInt(VERSION_UID_WITH_IDENT); - final int size = mUidStats.size(); + out.writeInt(mUidStats.size()); + for (NetworkIdentitySet ident : mUidStats.keySet()) { + final SparseArray<NetworkStatsHistory> uidStats = mUidStats.get(ident); + ident.writeToStream(out); - out.writeInt(size); - for (int i = 0; i < size; i++) { - final int uid = mUidStats.keyAt(i); - final NetworkStatsHistory history = mUidStats.valueAt(i); - out.writeInt(uid); - history.writeToStream(out); + final int size = uidStats.size(); + out.writeInt(size); + for (int i = 0; i < size; i++) { + final int uid = uidStats.keyAt(i); + final NetworkStatsHistory history = uidStats.valueAt(i); + out.writeInt(uid); + history.writeToStream(out); + } } mUidFile.finishWrite(fos); @@ -740,35 +785,41 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } if (argSet.contains("poll")) { - performPollLocked(true); + performPollLocked(true, true); pw.println("Forced poll"); return; } pw.println("Active interfaces:"); - for (String iface : mActiveIface.keySet()) { - final InterfaceIdentity ident = mActiveIface.get(iface); + for (String iface : mActiveIfaces.keySet()) { + final NetworkIdentitySet ident = mActiveIfaces.get(iface); pw.print(" iface="); pw.print(iface); pw.print(" ident="); pw.println(ident.toString()); } pw.println("Known historical stats:"); - for (InterfaceIdentity ident : mNetworkStats.keySet()) { - final NetworkStatsHistory stats = mNetworkStats.get(ident); + for (NetworkIdentitySet ident : mNetworkStats.keySet()) { + final NetworkStatsHistory history = mNetworkStats.get(ident); pw.print(" ident="); pw.println(ident.toString()); - stats.dump(" ", pw); + history.dump(" ", pw); } if (argSet.contains("detail")) { // since explicitly requested with argument, we're okay to load // from disk if not already in memory. ensureUidStatsLoadedLocked(); - pw.println("Known UID stats:"); - for (int i = 0; i < mUidStats.size(); i++) { - final int uid = mUidStats.keyAt(i); - final NetworkStatsHistory stats = mUidStats.valueAt(i); - pw.print(" UID="); pw.println(uid); - stats.dump(" ", pw); + + pw.println("Detailed UID stats:"); + for (NetworkIdentitySet ident : mUidStats.keySet()) { + pw.print(" ident="); pw.println(ident.toString()); + + final SparseArray<NetworkStatsHistory> uidStats = mUidStats.get(ident); + for (int i = 0; i < uidStats.size(); i++) { + final int uid = uidStats.keyAt(i); + final NetworkStatsHistory history = uidStats.valueAt(i); + pw.print(" UID="); pw.println(uid); + history.dump(" ", pw); + } } } } @@ -779,27 +830,30 @@ public class NetworkStatsService extends INetworkStatsService.Stub { */ @Deprecated private void generateRandomLocked() { - long end = System.currentTimeMillis(); - long start = end - mSettings.getNetworkMaxHistory(); - long rx = 3 * GB_IN_BYTES; - long tx = 2 * GB_IN_BYTES; + long networkEnd = System.currentTimeMillis(); + long networkStart = networkEnd - mSettings.getNetworkMaxHistory(); + long networkRx = 3 * GB_IN_BYTES; + long networkTx = 2 * GB_IN_BYTES; - mNetworkStats.clear(); - for (InterfaceIdentity ident : mActiveIface.values()) { - final NetworkStatsHistory stats = findOrCreateNetworkLocked(ident); - stats.generateRandom(start, end, rx, tx); - } + long uidEnd = System.currentTimeMillis(); + long uidStart = uidEnd - mSettings.getUidMaxHistory(); + long uidRx = 500 * MB_IN_BYTES; + long uidTx = 100 * MB_IN_BYTES; - end = System.currentTimeMillis(); - start = end - mSettings.getUidMaxHistory(); - rx = 500 * MB_IN_BYTES; - tx = 100 * MB_IN_BYTES; + final List<ApplicationInfo> installedApps = mContext + .getPackageManager().getInstalledApplications(0); + mNetworkStats.clear(); mUidStats.clear(); - for (ApplicationInfo info : mContext.getPackageManager().getInstalledApplications(0)) { - final int uid = info.uid; - final NetworkStatsHistory stats = findOrCreateUidLocked(uid); - stats.generateRandom(start, end, rx, tx); + for (NetworkIdentitySet ident : mActiveIfaces.values()) { + findOrCreateNetworkStatsLocked(ident).generateRandom( + networkStart, networkEnd, networkRx, networkTx); + + for (ApplicationInfo info : installedApps) { + final int uid = info.uid; + findOrCreateUidStatsLocked(ident, uid).generateRandom( + uidStart, uidEnd, uidRx, uidTx); + } } } @@ -815,12 +869,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } } - private String getActiveSubscriberId() { - final TelephonyManager telephony = (TelephonyManager) mContext.getSystemService( - Context.TELEPHONY_SERVICE); - return telephony.getSubscriberId(); - } - private int estimateNetworkBuckets() { return (int) (mSettings.getNetworkMaxHistory() / mSettings.getNetworkBucketDuration()); } @@ -834,6 +882,19 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } /** + * Test if given {@link NetworkTemplate} matches any {@link NetworkIdentity} + * in the given {@link NetworkIdentitySet}. + */ + private static boolean templateMatches(NetworkTemplate template, NetworkIdentitySet identSet) { + for (NetworkIdentity ident : identSet) { + if (template.matches(ident)) { + return true; + } + } + return false; + } + + /** * Default external settings that read from {@link Settings.Secure}. */ private static class DefaultNetworkStatsSettings implements NetworkStatsSettings { |