Loading core/java/android/net/NetworkStats.java +15 −0 Original line number Diff line number Diff line Loading @@ -102,6 +102,21 @@ public class NetworkStats implements Parcelable { this.txPackets = txPackets; this.operations = operations; } @Override public String toString() { final StringBuilder builder = new StringBuilder(); builder.append("iface=").append(iface); builder.append(" uid=").append(uid); builder.append(" set=").append(setToString(set)); builder.append(" tag=").append(tagToString(tag)); builder.append(" rxBytes=").append(rxBytes); builder.append(" rxPackets=").append(rxPackets); builder.append(" txBytes=").append(txBytes); builder.append(" txPackets=").append(txPackets); builder.append(" operations=").append(operations); return builder.toString(); } } public NetworkStats(long elapsedRealtime, int initialSize) { Loading services/java/com/android/server/NetworkManagementService.java +27 −20 Original line number Diff line number Diff line Loading @@ -98,6 +98,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub public static final String LIMIT_GLOBAL_ALERT = "globalAlert"; /** {@link #mStatsXtUid} headers. */ private static final String KEY_IDX = "idx"; private static final String KEY_IFACE = "iface"; private static final String KEY_UID = "uid_tag_int"; private static final String KEY_COUNTER_SET = "cnt_set"; Loading Loading @@ -1323,17 +1324,20 @@ public class NetworkManagementService extends INetworkManagementService.Stub // TODO: remove knownLines check once 5087722 verified final HashSet<String> knownLines = Sets.newHashSet(); // TODO: remove lastIdx check once 5270106 verified int lastIdx = 0; final ArrayList<String> keys = Lists.newArrayList(); final ArrayList<String> values = Lists.newArrayList(); final HashMap<String, String> parsed = Maps.newHashMap(); BufferedReader reader = null; String line = null; try { reader = new BufferedReader(new FileReader(mStatsXtUid)); // parse first line as header String line = reader.readLine(); line = reader.readLine(); splitLine(line, keys); // parse remaining lines Loading @@ -1342,10 +1346,16 @@ public class NetworkManagementService extends INetworkManagementService.Stub parseLine(keys, values, parsed); if (!knownLines.add(line)) { throw new IllegalStateException("encountered duplicate proc entry"); throw new IllegalStateException("duplicate proc entry: " + line); } try { final int idx = getParsedInt(parsed, KEY_IDX); if (idx > lastIdx + 1) { throw new IllegalStateException( "inconsistent idx=" + idx + " after lastIdx=" + lastIdx); } lastIdx = idx; entry.iface = parsed.get(KEY_IFACE); entry.uid = getParsedInt(parsed, KEY_UID); entry.set = getParsedInt(parsed, KEY_COUNTER_SET); Loading @@ -1358,16 +1368,13 @@ public class NetworkManagementService extends INetworkManagementService.Stub if (limitUid == UID_ALL || limitUid == entry.uid) { stats.addValues(entry); } } catch (NumberFormatException e) { Slog.w(TAG, "problem parsing stats row '" + line + "': " + e); } } } catch (NullPointerException e) { throw new IllegalStateException("problem parsing stats: " + e); throw new IllegalStateException("problem parsing line: " + line, e); } catch (NumberFormatException e) { throw new IllegalStateException("problem parsing stats: " + e); throw new IllegalStateException("problem parsing line: " + line, e); } catch (IOException e) { throw new IllegalStateException("problem parsing stats: " + e); throw new IllegalStateException("problem parsing line: " + line, e); } finally { IoUtils.closeQuietly(reader); } Loading services/java/com/android/server/net/NetworkPolicyManagerService.java +21 −58 Original line number Diff line number Diff line Loading @@ -100,6 +100,7 @@ import android.provider.Settings; import android.telephony.TelephonyManager; import android.text.format.Formatter; import android.text.format.Time; import android.util.Log; import android.util.NtpTrustedTime; import android.util.Slog; import android.util.SparseArray; Loading Loading @@ -298,18 +299,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { try { mActivityManager.registerProcessObserver(mProcessObserver); } catch (RemoteException e) { // ouch, no foregroundActivities updates means some processes may // never get network access. Slog.e(TAG, "unable to register IProcessObserver", e); } try { mNetworkManager.registerObserver(mAlertObserver); } catch (RemoteException e) { // ouch, no alert updates means we fall back to // ACTION_NETWORK_STATS_UPDATED broadcasts. Slog.e(TAG, "unable to register INetworkManagementEventObserver", e); // ignored; both services live in system_server } // TODO: traverse existing processes to know foreground state, or have Loading Loading @@ -462,7 +454,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // caused alert to trigger. mNetworkStats.forceUpdate(); } catch (RemoteException e) { Slog.w(TAG, "problem updating network stats"); // ignored; service lives in system_server } updateNetworkEnabledLocked(); Loading Loading @@ -495,9 +487,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final long start = computeLastCycleBoundary(currentTime, policy); final long end = currentTime; final long totalBytes = getTotalBytes(policy.template, start, end); if (totalBytes == UNKNOWN_BYTES) continue; if (policy.limitBytes != LIMIT_DISABLED && totalBytes >= policy.limitBytes) { if (policy.lastSnooze >= start) { Loading Loading @@ -671,7 +661,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { packageName, tag, 0x0, builder.getNotification(), idReceived); mActiveNotifs.add(tag); } catch (RemoteException e) { Slog.w(TAG, "problem during enqueueNotification: " + e); // ignored; service lives in system_server } } Loading Loading @@ -705,7 +695,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 0x0, builder.getNotification(), idReceived); mActiveNotifs.add(tag); } catch (RemoteException e) { Slog.w(TAG, "problem during enqueueNotification: " + e); // ignored; service lives in system_server } } Loading @@ -716,7 +706,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mNotifManager.cancelNotificationWithTag( packageName, tag, 0x0); } catch (RemoteException e) { Slog.w(TAG, "problem during enqueueNotification: " + e); // ignored; service lives in system_server } } Loading Loading @@ -758,9 +748,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final long start = computeLastCycleBoundary(currentTime, policy); final long end = currentTime; final long totalBytes = getTotalBytes(policy.template, start, end); if (totalBytes == UNKNOWN_BYTES) continue; // disable data connection when over limit and not snoozed final boolean overLimit = policy.limitBytes != LIMIT_DISABLED Loading Loading @@ -810,7 +798,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { try { states = mConnManager.getAllNetworkState(); } catch (RemoteException e) { Slog.w(TAG, "problem reading network state"); // ignored; service lives in system_server return; } Loading Loading @@ -857,9 +845,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final long start = computeLastCycleBoundary(currentTime, policy); final long end = currentTime; final long totalBytes = getTotalBytes(policy.template, start, end); if (totalBytes == UNKNOWN_BYTES) continue; if (LOGD) { Slog.d(TAG, "applying policy " + policy.toString() + " to ifaces " Loading Loading @@ -1006,9 +992,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // missing policy is okay, probably first boot upgradeLegacyBackgroundData(); } catch (IOException e) { Slog.e(TAG, "problem reading network stats", e); Log.wtf(TAG, "problem reading network policy", e); } catch (XmlPullParserException e) { Slog.e(TAG, "problem reading network stats", e); Log.wtf(TAG, "problem reading network policy", e); } finally { IoUtils.closeQuietly(fis); } Loading Loading @@ -1246,12 +1232,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final long currentTime = currentTimeMillis(false); // find total bytes used under policy final long start = computeLastCycleBoundary(currentTime, policy); final long end = currentTime; // find total bytes used under policy final long totalBytes = getTotalBytes(policy.template, start, end); if (totalBytes == UNKNOWN_BYTES) return null; // report soft and hard limits under policy final long softLimitBytes = policy.warningBytes != WARNING_DISABLED ? policy.warningBytes Loading Loading @@ -1369,6 +1353,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { try { mScreenOn = mPowerManager.isScreenOn(); } catch (RemoteException e) { // ignored; service lives in system_server } updateRulesForScreenLocked(); } Loading Loading @@ -1448,7 +1433,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // adjust stats accounting based on foreground status mNetworkStats.setUidForeground(uid, uidForeground); } catch (RemoteException e) { Slog.w(TAG, "problem dispatching foreground change"); // ignored; service lives in system_server } } Loading Loading @@ -1498,9 +1483,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { try { mNetworkManager.setInterfaceQuota(iface, quotaBytes); } catch (IllegalStateException e) { Slog.e(TAG, "problem setting interface quota", e); Log.wtf(TAG, "problem setting interface quota", e); } catch (RemoteException e) { Slog.e(TAG, "problem setting interface quota", e); // ignored; service lives in system_server } } Loading @@ -1508,29 +1493,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { try { mNetworkManager.removeInterfaceQuota(iface); } catch (IllegalStateException e) { Slog.e(TAG, "problem removing interface quota", e); Log.wtf(TAG, "problem removing interface quota", e); } catch (RemoteException e) { Slog.e(TAG, "problem removing interface quota", e); } } private void setInterfaceAlert(String iface, long alertBytes) { try { mNetworkManager.setInterfaceAlert(iface, alertBytes); } catch (IllegalStateException e) { Slog.e(TAG, "problem setting interface alert", e); } catch (RemoteException e) { Slog.e(TAG, "problem setting interface alert", e); } } private void removeInterfaceAlert(String iface) { try { mNetworkManager.removeInterfaceAlert(iface); } catch (IllegalStateException e) { Slog.e(TAG, "problem removing interface alert", e); } catch (RemoteException e) { Slog.e(TAG, "problem removing interface alert", e); // ignored; service lives in system_server } } Loading @@ -1538,9 +1503,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { try { mNetworkManager.setUidNetworkRules(uid, rejectOnQuotaInterfaces); } catch (IllegalStateException e) { Slog.e(TAG, "problem setting uid rules", e); Log.wtf(TAG, "problem setting uid rules", e); } catch (RemoteException e) { Slog.e(TAG, "problem setting uid rules", e); // ignored; service lives in system_server } } Loading @@ -1556,7 +1521,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { try { mConnManager.setPolicyDataEnable(networkType, enabled); } catch (RemoteException e) { Slog.e(TAG, "problem setting network enabled", e); // ignored; service lives in system_server } mActiveNetworkEnabled.put(networkType, enabled); Loading @@ -1569,8 +1534,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return telephony.getSubscriberId(); } private static final long UNKNOWN_BYTES = -1; private long getTotalBytes(NetworkTemplate template, long start, long end) { try { final NetworkStats stats = mNetworkStats.getSummaryForNetwork( Loading @@ -1578,8 +1541,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final NetworkStats.Entry entry = stats.getValues(0, null); return entry.rxBytes + entry.txBytes; } catch (RemoteException e) { Slog.w(TAG, "problem reading summary for template " + template); return UNKNOWN_BYTES; // ignored; service lives in system_server return 0; } } Loading services/java/com/android/server/net/NetworkStatsService.java +79 −63 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ import android.os.SystemClock; import android.provider.Settings; import android.telephony.TelephonyManager; import android.util.EventLog; import android.util.Log; import android.util.NtpTrustedTime; import android.util.Slog; import android.util.SparseIntArray; Loading Loading @@ -128,7 +129,16 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private static final int VERSION_UID_WITH_SET = 4; private static final int MSG_PERFORM_POLL = 0x1; private static final int MSG_PERFORM_POLL_DETAILED = 0x2; /** Flags to control detail level of poll event. */ private static final int FLAG_POLL_NETWORK = 0x1; private static final int FLAG_POLL_UID = 0x2; private static final int FLAG_PERSIST_NETWORK = 0x10; private static final int FLAG_PERSIST_UID = 0x20; private static final int FLAG_FORCE_PERSIST = 0x100; private static final int FLAG_POLL_ALL = FLAG_POLL_NETWORK | FLAG_POLL_UID; private static final int FLAG_PERSIST_ALL = FLAG_PERSIST_NETWORK | FLAG_PERSIST_UID; private final Context mContext; private final INetworkManagementService mNetworkManager; Loading Loading @@ -261,9 +271,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { try { mNetworkManager.registerObserver(mAlertObserver); } catch (RemoteException e) { // ouch, no push updates means we fall back to // ACTION_NETWORK_STATS_POLL intervals. Slog.e(TAG, "unable to register INetworkManagementEventObserver", e); // ignored; service lives in system_server } registerPollAlarmLocked(); Loading Loading @@ -305,7 +313,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime, mSettings.getPollInterval(), mPollIntent); } catch (RemoteException e) { Slog.w(TAG, "problem registering for poll alarm: " + e); // ignored; service lives in system_server } } Loading @@ -321,7 +329,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } catch (IllegalStateException e) { Slog.w(TAG, "problem registering for global alert: " + e); } catch (RemoteException e) { Slog.w(TAG, "problem registering for global alert: " + e); // ignored; service lives in system_server } } Loading Loading @@ -509,7 +517,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @Override public void forceUpdate() { mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG); performPoll(true, false); performPoll(FLAG_POLL_ALL | FLAG_PERSIST_ALL); } /** Loading Loading @@ -538,7 +546,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { public void onReceive(Context context, Intent intent) { // on background handler thread, and verified UPDATE_DEVICE_STATS // permission above. performPoll(true, false); performPoll(FLAG_POLL_ALL | FLAG_PERSIST_ALL); // verify that we're watching global alert registerGlobalAlert(); Loading Loading @@ -585,7 +593,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { if (LIMIT_GLOBAL_ALERT.equals(limitName)) { // kick off background poll to collect network stats; UID stats // are handled during normal polling interval. mHandler.obtainMessage(MSG_PERFORM_POLL).sendToTarget(); final int flags = FLAG_POLL_NETWORK | FLAG_PERSIST_NETWORK; mHandler.obtainMessage(MSG_PERFORM_POLL, flags, 0).sendToTarget(); // re-arm global alert for next update registerGlobalAlert(); Loading @@ -605,13 +614,17 @@ 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, false); // poll both network and UID stats, but only persist network stats, // since this codepath should stay fast. UID stats will be persisted // during next alarm poll event. performPollLocked(FLAG_POLL_ALL | FLAG_PERSIST_NETWORK); final NetworkState[] states; try { states = mConnManager.getAllNetworkState(); } catch (RemoteException e) { Slog.w(TAG, "problem reading network state"); // ignored; service lives in system_server return; } Loading Loading @@ -646,15 +659,15 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } catch (IllegalStateException e) { Slog.w(TAG, "problem reading network stats: " + e); } catch (RemoteException e) { Slog.w(TAG, "problem reading network stats: " + e); // ignored; service lives in system_server } } private void performPoll(boolean detailedPoll, boolean forcePersist) { private void performPoll(int flags) { synchronized (mStatsLock) { mWakeLock.acquire(); try { performPollLocked(detailedPoll, forcePersist); performPollLocked(flags); } finally { mWakeLock.release(); } Loading @@ -664,14 +677,17 @@ public class NetworkStatsService extends INetworkStatsService.Stub { /** * Periodic poll operation, reading current statistics and recording into * {@link NetworkStatsHistory}. * * @param detailedPoll Indicate if detailed UID stats should be collected * during this poll operation. */ private void performPollLocked(boolean detailedPoll, boolean forcePersist) { if (LOGV) Slog.v(TAG, "performPollLocked()"); private void performPollLocked(int flags) { if (LOGV) Slog.v(TAG, "performPollLocked(flags=0x" + Integer.toHexString(flags) + ")"); final long startRealtime = SystemClock.elapsedRealtime(); final boolean pollNetwork = (flags & FLAG_POLL_NETWORK) != 0; final boolean pollUid = (flags & FLAG_POLL_UID) != 0; final boolean persistNetwork = (flags & FLAG_PERSIST_NETWORK) != 0; final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0; final boolean forcePersist = (flags & FLAG_FORCE_PERSIST) != 0; // try refreshing time source when stale if (mTime.getCacheAge() > mSettings.getTimeCacheMaxAge()) { mTime.forceRefresh(); Loading @@ -680,50 +696,49 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // TODO: consider marking "untrusted" times in historical stats final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis(); final long persistThreshold = mSettings.getPersistThreshold(); final long threshold = mSettings.getPersistThreshold(); final NetworkStats networkSnapshot; final NetworkStats uidSnapshot; try { networkSnapshot = mNetworkManager.getNetworkStatsSummary(); uidSnapshot = detailedPoll ? mNetworkManager.getNetworkStatsUidDetail(UID_ALL) : null; } catch (IllegalStateException e) { Slog.w(TAG, "problem reading network stats: " + e); return; } catch (RemoteException e) { Slog.w(TAG, "problem reading network stats: " + e); return; } if (pollNetwork) { final NetworkStats networkSnapshot = mNetworkManager.getNetworkStatsSummary(); performNetworkPollLocked(networkSnapshot, currentTime); // persist when enough network data has occurred final NetworkStats persistNetworkDelta = computeStatsDelta( mLastPersistNetworkSnapshot, networkSnapshot, true); if (forcePersist || persistNetworkDelta.getTotalBytes() > persistThreshold) { final boolean pastThreshold = persistNetworkDelta.getTotalBytes() > threshold; if (forcePersist || (persistNetwork && pastThreshold)) { writeNetworkStatsLocked(); mLastPersistNetworkSnapshot = networkSnapshot; } } if (detailedPoll) { if (pollUid) { final NetworkStats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL); performUidPollLocked(uidSnapshot, currentTime); // persist when enough network data has occurred final NetworkStats persistUidDelta = computeStatsDelta( mLastPersistUidSnapshot, uidSnapshot, true); if (forcePersist || persistUidDelta.getTotalBytes() > persistThreshold) { final boolean pastThreshold = persistUidDelta.getTotalBytes() > threshold; if (forcePersist || (persistUid && pastThreshold)) { writeUidStatsLocked(); mLastPersistUidSnapshot = networkSnapshot; mLastPersistUidSnapshot = uidSnapshot; } } } catch (IllegalStateException e) { Log.wtf(TAG, "problem reading network stats", e); } catch (RemoteException e) { // ignored; service lives in system_server } if (LOGV) { final long duration = SystemClock.elapsedRealtime() - startRealtime; Slog.v(TAG, "performPollLocked() took " + duration + "ms"); } // sample stats after detailed poll if (detailedPoll) { // sample stats after each full poll if (pollNetwork && pollUid) { performSample(); } Loading Loading @@ -785,6 +800,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { entry = delta.getValues(i, entry); final NetworkIdentitySet ident = mActiveIfaces.get(entry.iface); if (ident == null) { if (entry.rxBytes > 0 || entry.rxPackets > 0 || entry.txBytes > 0 || entry.txPackets > 0) { Log.w(TAG, "dropping UID delta from unknown iface: " + entry); } continue; } Loading Loading @@ -959,7 +978,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } catch (FileNotFoundException e) { // missing stats is okay, probably first boot } catch (IOException e) { Slog.e(TAG, "problem reading network stats", e); Log.wtf(TAG, "problem reading network stats", e); } finally { IoUtils.closeQuietly(in); } Loading Loading @@ -1032,7 +1051,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } catch (FileNotFoundException e) { // missing stats is okay, probably first boot } catch (IOException e) { Slog.e(TAG, "problem reading uid stats", e); Log.wtf(TAG, "problem reading uid stats", e); } finally { IoUtils.closeQuietly(in); } Loading Loading @@ -1061,7 +1080,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { out.flush(); mNetworkFile.finishWrite(fos); } catch (IOException e) { Slog.w(TAG, "problem writing stats: ", e); Log.wtf(TAG, "problem writing stats", e); if (fos != null) { mNetworkFile.failWrite(fos); } Loading Loading @@ -1115,7 +1134,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { out.flush(); mUidFile.finishWrite(fos); } catch (IOException e) { Slog.w(TAG, "problem writing stats: ", e); Log.wtf(TAG, "problem writing stats", e); if (fos != null) { mUidFile.failWrite(fos); } Loading @@ -1142,7 +1161,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } if (argSet.contains("poll")) { performPollLocked(true, true); performPollLocked(FLAG_POLL_ALL | FLAG_PERSIST_ALL | FLAG_FORCE_PERSIST); pw.println("Forced poll"); return; } Loading Loading @@ -1273,11 +1292,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { public boolean handleMessage(Message msg) { switch (msg.what) { case MSG_PERFORM_POLL: { performPoll(false, false); return true; } case MSG_PERFORM_POLL_DETAILED: { performPoll(true, false); final int flags = msg.arg1; performPoll(flags); return true; } default: { Loading Loading @@ -1349,7 +1365,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { return getSecureLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS); } public long getPersistThreshold() { return getSecureLong(NETSTATS_PERSIST_THRESHOLD, 512 * KB_IN_BYTES); return getSecureLong(NETSTATS_PERSIST_THRESHOLD, 2 * MB_IN_BYTES); } public long getNetworkBucketDuration() { return getSecureLong(NETSTATS_NETWORK_BUCKET_DURATION, HOUR_IN_MILLIS); Loading services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java +8 −0 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/net/NetworkStats.java +15 −0 Original line number Diff line number Diff line Loading @@ -102,6 +102,21 @@ public class NetworkStats implements Parcelable { this.txPackets = txPackets; this.operations = operations; } @Override public String toString() { final StringBuilder builder = new StringBuilder(); builder.append("iface=").append(iface); builder.append(" uid=").append(uid); builder.append(" set=").append(setToString(set)); builder.append(" tag=").append(tagToString(tag)); builder.append(" rxBytes=").append(rxBytes); builder.append(" rxPackets=").append(rxPackets); builder.append(" txBytes=").append(txBytes); builder.append(" txPackets=").append(txPackets); builder.append(" operations=").append(operations); return builder.toString(); } } public NetworkStats(long elapsedRealtime, int initialSize) { Loading
services/java/com/android/server/NetworkManagementService.java +27 −20 Original line number Diff line number Diff line Loading @@ -98,6 +98,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub public static final String LIMIT_GLOBAL_ALERT = "globalAlert"; /** {@link #mStatsXtUid} headers. */ private static final String KEY_IDX = "idx"; private static final String KEY_IFACE = "iface"; private static final String KEY_UID = "uid_tag_int"; private static final String KEY_COUNTER_SET = "cnt_set"; Loading Loading @@ -1323,17 +1324,20 @@ public class NetworkManagementService extends INetworkManagementService.Stub // TODO: remove knownLines check once 5087722 verified final HashSet<String> knownLines = Sets.newHashSet(); // TODO: remove lastIdx check once 5270106 verified int lastIdx = 0; final ArrayList<String> keys = Lists.newArrayList(); final ArrayList<String> values = Lists.newArrayList(); final HashMap<String, String> parsed = Maps.newHashMap(); BufferedReader reader = null; String line = null; try { reader = new BufferedReader(new FileReader(mStatsXtUid)); // parse first line as header String line = reader.readLine(); line = reader.readLine(); splitLine(line, keys); // parse remaining lines Loading @@ -1342,10 +1346,16 @@ public class NetworkManagementService extends INetworkManagementService.Stub parseLine(keys, values, parsed); if (!knownLines.add(line)) { throw new IllegalStateException("encountered duplicate proc entry"); throw new IllegalStateException("duplicate proc entry: " + line); } try { final int idx = getParsedInt(parsed, KEY_IDX); if (idx > lastIdx + 1) { throw new IllegalStateException( "inconsistent idx=" + idx + " after lastIdx=" + lastIdx); } lastIdx = idx; entry.iface = parsed.get(KEY_IFACE); entry.uid = getParsedInt(parsed, KEY_UID); entry.set = getParsedInt(parsed, KEY_COUNTER_SET); Loading @@ -1358,16 +1368,13 @@ public class NetworkManagementService extends INetworkManagementService.Stub if (limitUid == UID_ALL || limitUid == entry.uid) { stats.addValues(entry); } } catch (NumberFormatException e) { Slog.w(TAG, "problem parsing stats row '" + line + "': " + e); } } } catch (NullPointerException e) { throw new IllegalStateException("problem parsing stats: " + e); throw new IllegalStateException("problem parsing line: " + line, e); } catch (NumberFormatException e) { throw new IllegalStateException("problem parsing stats: " + e); throw new IllegalStateException("problem parsing line: " + line, e); } catch (IOException e) { throw new IllegalStateException("problem parsing stats: " + e); throw new IllegalStateException("problem parsing line: " + line, e); } finally { IoUtils.closeQuietly(reader); } Loading
services/java/com/android/server/net/NetworkPolicyManagerService.java +21 −58 Original line number Diff line number Diff line Loading @@ -100,6 +100,7 @@ import android.provider.Settings; import android.telephony.TelephonyManager; import android.text.format.Formatter; import android.text.format.Time; import android.util.Log; import android.util.NtpTrustedTime; import android.util.Slog; import android.util.SparseArray; Loading Loading @@ -298,18 +299,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { try { mActivityManager.registerProcessObserver(mProcessObserver); } catch (RemoteException e) { // ouch, no foregroundActivities updates means some processes may // never get network access. Slog.e(TAG, "unable to register IProcessObserver", e); } try { mNetworkManager.registerObserver(mAlertObserver); } catch (RemoteException e) { // ouch, no alert updates means we fall back to // ACTION_NETWORK_STATS_UPDATED broadcasts. Slog.e(TAG, "unable to register INetworkManagementEventObserver", e); // ignored; both services live in system_server } // TODO: traverse existing processes to know foreground state, or have Loading Loading @@ -462,7 +454,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // caused alert to trigger. mNetworkStats.forceUpdate(); } catch (RemoteException e) { Slog.w(TAG, "problem updating network stats"); // ignored; service lives in system_server } updateNetworkEnabledLocked(); Loading Loading @@ -495,9 +487,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final long start = computeLastCycleBoundary(currentTime, policy); final long end = currentTime; final long totalBytes = getTotalBytes(policy.template, start, end); if (totalBytes == UNKNOWN_BYTES) continue; if (policy.limitBytes != LIMIT_DISABLED && totalBytes >= policy.limitBytes) { if (policy.lastSnooze >= start) { Loading Loading @@ -671,7 +661,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { packageName, tag, 0x0, builder.getNotification(), idReceived); mActiveNotifs.add(tag); } catch (RemoteException e) { Slog.w(TAG, "problem during enqueueNotification: " + e); // ignored; service lives in system_server } } Loading Loading @@ -705,7 +695,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 0x0, builder.getNotification(), idReceived); mActiveNotifs.add(tag); } catch (RemoteException e) { Slog.w(TAG, "problem during enqueueNotification: " + e); // ignored; service lives in system_server } } Loading @@ -716,7 +706,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mNotifManager.cancelNotificationWithTag( packageName, tag, 0x0); } catch (RemoteException e) { Slog.w(TAG, "problem during enqueueNotification: " + e); // ignored; service lives in system_server } } Loading Loading @@ -758,9 +748,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final long start = computeLastCycleBoundary(currentTime, policy); final long end = currentTime; final long totalBytes = getTotalBytes(policy.template, start, end); if (totalBytes == UNKNOWN_BYTES) continue; // disable data connection when over limit and not snoozed final boolean overLimit = policy.limitBytes != LIMIT_DISABLED Loading Loading @@ -810,7 +798,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { try { states = mConnManager.getAllNetworkState(); } catch (RemoteException e) { Slog.w(TAG, "problem reading network state"); // ignored; service lives in system_server return; } Loading Loading @@ -857,9 +845,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final long start = computeLastCycleBoundary(currentTime, policy); final long end = currentTime; final long totalBytes = getTotalBytes(policy.template, start, end); if (totalBytes == UNKNOWN_BYTES) continue; if (LOGD) { Slog.d(TAG, "applying policy " + policy.toString() + " to ifaces " Loading Loading @@ -1006,9 +992,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // missing policy is okay, probably first boot upgradeLegacyBackgroundData(); } catch (IOException e) { Slog.e(TAG, "problem reading network stats", e); Log.wtf(TAG, "problem reading network policy", e); } catch (XmlPullParserException e) { Slog.e(TAG, "problem reading network stats", e); Log.wtf(TAG, "problem reading network policy", e); } finally { IoUtils.closeQuietly(fis); } Loading Loading @@ -1246,12 +1232,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final long currentTime = currentTimeMillis(false); // find total bytes used under policy final long start = computeLastCycleBoundary(currentTime, policy); final long end = currentTime; // find total bytes used under policy final long totalBytes = getTotalBytes(policy.template, start, end); if (totalBytes == UNKNOWN_BYTES) return null; // report soft and hard limits under policy final long softLimitBytes = policy.warningBytes != WARNING_DISABLED ? policy.warningBytes Loading Loading @@ -1369,6 +1353,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { try { mScreenOn = mPowerManager.isScreenOn(); } catch (RemoteException e) { // ignored; service lives in system_server } updateRulesForScreenLocked(); } Loading Loading @@ -1448,7 +1433,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // adjust stats accounting based on foreground status mNetworkStats.setUidForeground(uid, uidForeground); } catch (RemoteException e) { Slog.w(TAG, "problem dispatching foreground change"); // ignored; service lives in system_server } } Loading Loading @@ -1498,9 +1483,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { try { mNetworkManager.setInterfaceQuota(iface, quotaBytes); } catch (IllegalStateException e) { Slog.e(TAG, "problem setting interface quota", e); Log.wtf(TAG, "problem setting interface quota", e); } catch (RemoteException e) { Slog.e(TAG, "problem setting interface quota", e); // ignored; service lives in system_server } } Loading @@ -1508,29 +1493,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { try { mNetworkManager.removeInterfaceQuota(iface); } catch (IllegalStateException e) { Slog.e(TAG, "problem removing interface quota", e); Log.wtf(TAG, "problem removing interface quota", e); } catch (RemoteException e) { Slog.e(TAG, "problem removing interface quota", e); } } private void setInterfaceAlert(String iface, long alertBytes) { try { mNetworkManager.setInterfaceAlert(iface, alertBytes); } catch (IllegalStateException e) { Slog.e(TAG, "problem setting interface alert", e); } catch (RemoteException e) { Slog.e(TAG, "problem setting interface alert", e); } } private void removeInterfaceAlert(String iface) { try { mNetworkManager.removeInterfaceAlert(iface); } catch (IllegalStateException e) { Slog.e(TAG, "problem removing interface alert", e); } catch (RemoteException e) { Slog.e(TAG, "problem removing interface alert", e); // ignored; service lives in system_server } } Loading @@ -1538,9 +1503,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { try { mNetworkManager.setUidNetworkRules(uid, rejectOnQuotaInterfaces); } catch (IllegalStateException e) { Slog.e(TAG, "problem setting uid rules", e); Log.wtf(TAG, "problem setting uid rules", e); } catch (RemoteException e) { Slog.e(TAG, "problem setting uid rules", e); // ignored; service lives in system_server } } Loading @@ -1556,7 +1521,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { try { mConnManager.setPolicyDataEnable(networkType, enabled); } catch (RemoteException e) { Slog.e(TAG, "problem setting network enabled", e); // ignored; service lives in system_server } mActiveNetworkEnabled.put(networkType, enabled); Loading @@ -1569,8 +1534,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return telephony.getSubscriberId(); } private static final long UNKNOWN_BYTES = -1; private long getTotalBytes(NetworkTemplate template, long start, long end) { try { final NetworkStats stats = mNetworkStats.getSummaryForNetwork( Loading @@ -1578,8 +1541,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final NetworkStats.Entry entry = stats.getValues(0, null); return entry.rxBytes + entry.txBytes; } catch (RemoteException e) { Slog.w(TAG, "problem reading summary for template " + template); return UNKNOWN_BYTES; // ignored; service lives in system_server return 0; } } Loading
services/java/com/android/server/net/NetworkStatsService.java +79 −63 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ import android.os.SystemClock; import android.provider.Settings; import android.telephony.TelephonyManager; import android.util.EventLog; import android.util.Log; import android.util.NtpTrustedTime; import android.util.Slog; import android.util.SparseIntArray; Loading Loading @@ -128,7 +129,16 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private static final int VERSION_UID_WITH_SET = 4; private static final int MSG_PERFORM_POLL = 0x1; private static final int MSG_PERFORM_POLL_DETAILED = 0x2; /** Flags to control detail level of poll event. */ private static final int FLAG_POLL_NETWORK = 0x1; private static final int FLAG_POLL_UID = 0x2; private static final int FLAG_PERSIST_NETWORK = 0x10; private static final int FLAG_PERSIST_UID = 0x20; private static final int FLAG_FORCE_PERSIST = 0x100; private static final int FLAG_POLL_ALL = FLAG_POLL_NETWORK | FLAG_POLL_UID; private static final int FLAG_PERSIST_ALL = FLAG_PERSIST_NETWORK | FLAG_PERSIST_UID; private final Context mContext; private final INetworkManagementService mNetworkManager; Loading Loading @@ -261,9 +271,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { try { mNetworkManager.registerObserver(mAlertObserver); } catch (RemoteException e) { // ouch, no push updates means we fall back to // ACTION_NETWORK_STATS_POLL intervals. Slog.e(TAG, "unable to register INetworkManagementEventObserver", e); // ignored; service lives in system_server } registerPollAlarmLocked(); Loading Loading @@ -305,7 +313,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime, mSettings.getPollInterval(), mPollIntent); } catch (RemoteException e) { Slog.w(TAG, "problem registering for poll alarm: " + e); // ignored; service lives in system_server } } Loading @@ -321,7 +329,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } catch (IllegalStateException e) { Slog.w(TAG, "problem registering for global alert: " + e); } catch (RemoteException e) { Slog.w(TAG, "problem registering for global alert: " + e); // ignored; service lives in system_server } } Loading Loading @@ -509,7 +517,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @Override public void forceUpdate() { mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG); performPoll(true, false); performPoll(FLAG_POLL_ALL | FLAG_PERSIST_ALL); } /** Loading Loading @@ -538,7 +546,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { public void onReceive(Context context, Intent intent) { // on background handler thread, and verified UPDATE_DEVICE_STATS // permission above. performPoll(true, false); performPoll(FLAG_POLL_ALL | FLAG_PERSIST_ALL); // verify that we're watching global alert registerGlobalAlert(); Loading Loading @@ -585,7 +593,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { if (LIMIT_GLOBAL_ALERT.equals(limitName)) { // kick off background poll to collect network stats; UID stats // are handled during normal polling interval. mHandler.obtainMessage(MSG_PERFORM_POLL).sendToTarget(); final int flags = FLAG_POLL_NETWORK | FLAG_PERSIST_NETWORK; mHandler.obtainMessage(MSG_PERFORM_POLL, flags, 0).sendToTarget(); // re-arm global alert for next update registerGlobalAlert(); Loading @@ -605,13 +614,17 @@ 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, false); // poll both network and UID stats, but only persist network stats, // since this codepath should stay fast. UID stats will be persisted // during next alarm poll event. performPollLocked(FLAG_POLL_ALL | FLAG_PERSIST_NETWORK); final NetworkState[] states; try { states = mConnManager.getAllNetworkState(); } catch (RemoteException e) { Slog.w(TAG, "problem reading network state"); // ignored; service lives in system_server return; } Loading Loading @@ -646,15 +659,15 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } catch (IllegalStateException e) { Slog.w(TAG, "problem reading network stats: " + e); } catch (RemoteException e) { Slog.w(TAG, "problem reading network stats: " + e); // ignored; service lives in system_server } } private void performPoll(boolean detailedPoll, boolean forcePersist) { private void performPoll(int flags) { synchronized (mStatsLock) { mWakeLock.acquire(); try { performPollLocked(detailedPoll, forcePersist); performPollLocked(flags); } finally { mWakeLock.release(); } Loading @@ -664,14 +677,17 @@ public class NetworkStatsService extends INetworkStatsService.Stub { /** * Periodic poll operation, reading current statistics and recording into * {@link NetworkStatsHistory}. * * @param detailedPoll Indicate if detailed UID stats should be collected * during this poll operation. */ private void performPollLocked(boolean detailedPoll, boolean forcePersist) { if (LOGV) Slog.v(TAG, "performPollLocked()"); private void performPollLocked(int flags) { if (LOGV) Slog.v(TAG, "performPollLocked(flags=0x" + Integer.toHexString(flags) + ")"); final long startRealtime = SystemClock.elapsedRealtime(); final boolean pollNetwork = (flags & FLAG_POLL_NETWORK) != 0; final boolean pollUid = (flags & FLAG_POLL_UID) != 0; final boolean persistNetwork = (flags & FLAG_PERSIST_NETWORK) != 0; final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0; final boolean forcePersist = (flags & FLAG_FORCE_PERSIST) != 0; // try refreshing time source when stale if (mTime.getCacheAge() > mSettings.getTimeCacheMaxAge()) { mTime.forceRefresh(); Loading @@ -680,50 +696,49 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // TODO: consider marking "untrusted" times in historical stats final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis(); final long persistThreshold = mSettings.getPersistThreshold(); final long threshold = mSettings.getPersistThreshold(); final NetworkStats networkSnapshot; final NetworkStats uidSnapshot; try { networkSnapshot = mNetworkManager.getNetworkStatsSummary(); uidSnapshot = detailedPoll ? mNetworkManager.getNetworkStatsUidDetail(UID_ALL) : null; } catch (IllegalStateException e) { Slog.w(TAG, "problem reading network stats: " + e); return; } catch (RemoteException e) { Slog.w(TAG, "problem reading network stats: " + e); return; } if (pollNetwork) { final NetworkStats networkSnapshot = mNetworkManager.getNetworkStatsSummary(); performNetworkPollLocked(networkSnapshot, currentTime); // persist when enough network data has occurred final NetworkStats persistNetworkDelta = computeStatsDelta( mLastPersistNetworkSnapshot, networkSnapshot, true); if (forcePersist || persistNetworkDelta.getTotalBytes() > persistThreshold) { final boolean pastThreshold = persistNetworkDelta.getTotalBytes() > threshold; if (forcePersist || (persistNetwork && pastThreshold)) { writeNetworkStatsLocked(); mLastPersistNetworkSnapshot = networkSnapshot; } } if (detailedPoll) { if (pollUid) { final NetworkStats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL); performUidPollLocked(uidSnapshot, currentTime); // persist when enough network data has occurred final NetworkStats persistUidDelta = computeStatsDelta( mLastPersistUidSnapshot, uidSnapshot, true); if (forcePersist || persistUidDelta.getTotalBytes() > persistThreshold) { final boolean pastThreshold = persistUidDelta.getTotalBytes() > threshold; if (forcePersist || (persistUid && pastThreshold)) { writeUidStatsLocked(); mLastPersistUidSnapshot = networkSnapshot; mLastPersistUidSnapshot = uidSnapshot; } } } catch (IllegalStateException e) { Log.wtf(TAG, "problem reading network stats", e); } catch (RemoteException e) { // ignored; service lives in system_server } if (LOGV) { final long duration = SystemClock.elapsedRealtime() - startRealtime; Slog.v(TAG, "performPollLocked() took " + duration + "ms"); } // sample stats after detailed poll if (detailedPoll) { // sample stats after each full poll if (pollNetwork && pollUid) { performSample(); } Loading Loading @@ -785,6 +800,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { entry = delta.getValues(i, entry); final NetworkIdentitySet ident = mActiveIfaces.get(entry.iface); if (ident == null) { if (entry.rxBytes > 0 || entry.rxPackets > 0 || entry.txBytes > 0 || entry.txPackets > 0) { Log.w(TAG, "dropping UID delta from unknown iface: " + entry); } continue; } Loading Loading @@ -959,7 +978,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } catch (FileNotFoundException e) { // missing stats is okay, probably first boot } catch (IOException e) { Slog.e(TAG, "problem reading network stats", e); Log.wtf(TAG, "problem reading network stats", e); } finally { IoUtils.closeQuietly(in); } Loading Loading @@ -1032,7 +1051,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } catch (FileNotFoundException e) { // missing stats is okay, probably first boot } catch (IOException e) { Slog.e(TAG, "problem reading uid stats", e); Log.wtf(TAG, "problem reading uid stats", e); } finally { IoUtils.closeQuietly(in); } Loading Loading @@ -1061,7 +1080,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { out.flush(); mNetworkFile.finishWrite(fos); } catch (IOException e) { Slog.w(TAG, "problem writing stats: ", e); Log.wtf(TAG, "problem writing stats", e); if (fos != null) { mNetworkFile.failWrite(fos); } Loading Loading @@ -1115,7 +1134,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { out.flush(); mUidFile.finishWrite(fos); } catch (IOException e) { Slog.w(TAG, "problem writing stats: ", e); Log.wtf(TAG, "problem writing stats", e); if (fos != null) { mUidFile.failWrite(fos); } Loading @@ -1142,7 +1161,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } if (argSet.contains("poll")) { performPollLocked(true, true); performPollLocked(FLAG_POLL_ALL | FLAG_PERSIST_ALL | FLAG_FORCE_PERSIST); pw.println("Forced poll"); return; } Loading Loading @@ -1273,11 +1292,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { public boolean handleMessage(Message msg) { switch (msg.what) { case MSG_PERFORM_POLL: { performPoll(false, false); return true; } case MSG_PERFORM_POLL_DETAILED: { performPoll(true, false); final int flags = msg.arg1; performPoll(flags); return true; } default: { Loading Loading @@ -1349,7 +1365,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { return getSecureLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS); } public long getPersistThreshold() { return getSecureLong(NETSTATS_PERSIST_THRESHOLD, 512 * KB_IN_BYTES); return getSecureLong(NETSTATS_PERSIST_THRESHOLD, 2 * MB_IN_BYTES); } public long getNetworkBucketDuration() { return getSecureLong(NETSTATS_NETWORK_BUCKET_DURATION, HOUR_IN_MILLIS); Loading
services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java +8 −0 File changed.Preview size limit exceeded, changes collapsed. Show changes