Loading core/java/android/net/NetworkStats.java +3 −2 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.os.Parcelable; import android.os.SystemClock; import android.util.SparseBooleanArray; import com.android.internal.util.ArrayUtils; import com.android.internal.util.Objects; import java.io.CharArrayWriter; Loading Loading @@ -608,13 +609,13 @@ public class NetworkStats implements Parcelable { * Return all rows except those attributed to the requested UID; doesn't * mutate the original structure. */ public NetworkStats withoutUid(int uid) { public NetworkStats withoutUids(int[] uids) { final NetworkStats stats = new NetworkStats(elapsedRealtime, 10); Entry entry = new Entry(); for (int i = 0; i < size; i++) { entry = getValues(i, entry); if (entry.uid != uid) { if (!ArrayUtils.contains(uids, entry.uid)) { stats.addValues(entry); } } Loading core/tests/coretests/src/android/net/NetworkStatsTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -287,7 +287,7 @@ public class NetworkStatsTest extends TestCase { .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L) .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 128L, 8L, 0L, 0L, 0L); final NetworkStats after = before.withoutUid(100); final NetworkStats after = before.withoutUids(new int[] { 100 }); assertEquals(6, before.size()); assertEquals(2, after.size()); assertValues(after, 0, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L); Loading services/java/com/android/server/net/NetworkStatsCollection.java +3 −2 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.net.TrafficStats; import android.text.format.DateUtils; import android.util.AtomicFile; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FileRotator; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Objects; Loading Loading @@ -431,13 +432,13 @@ public class NetworkStatsCollection implements FileRotator.Reader { * moving any {@link NetworkStats#TAG_NONE} series to * {@link TrafficStats#UID_REMOVED}. */ public void removeUid(int uid) { public void removeUids(int[] uids) { final ArrayList<Key> knownKeys = Lists.newArrayList(); knownKeys.addAll(mStats.keySet()); // migrate all UID stats into special "removed" bucket for (Key key : knownKeys) { if (key.uid == uid) { if (ArrayUtils.contains(uids, key.uid)) { // only migrate combined TAG_NONE history if (key.tag == TAG_NONE) { final NetworkStatsHistory uidHistory = mStats.get(key); Loading services/java/com/android/server/net/NetworkStatsRecorder.java +16 −11 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.ref.WeakReference; import java.util.Arrays; import java.util.HashSet; import java.util.Map; Loading Loading @@ -233,23 +234,27 @@ public class NetworkStatsRecorder { * Remove the given UID from all {@link FileRotator} history, migrating it * to {@link TrafficStats#UID_REMOVED}. */ public void removeUidLocked(int uid) { public void removeUidsLocked(int[] uids) { try { // process all existing data to migrate uid mRotator.rewriteAll(new RemoveUidRewriter(mBucketDuration, uid)); // Rewrite all persisted data to migrate UID stats mRotator.rewriteAll(new RemoveUidRewriter(mBucketDuration, uids)); } catch (IOException e) { Log.wtf(TAG, "problem removing UID " + uid, e); Log.wtf(TAG, "problem removing UIDs " + Arrays.toString(uids), e); recoverFromWtf(); } // clear UID from current stats snapshot // Remove any pending stats mPending.removeUids(uids); mSinceBoot.removeUids(uids); // Clear UID from current stats snapshot if (mLastSnapshot != null) { mLastSnapshot = mLastSnapshot.withoutUid(uid); mLastSnapshot = mLastSnapshot.withoutUids(uids); } final NetworkStatsCollection complete = mComplete != null ? mComplete.get() : null; if (complete != null) { complete.removeUid(uid); complete.removeUids(uids); } } Loading Loading @@ -293,11 +298,11 @@ public class NetworkStatsRecorder { */ public static class RemoveUidRewriter implements FileRotator.Rewriter { private final NetworkStatsCollection mTemp; private final int mUid; private final int[] mUids; public RemoveUidRewriter(long bucketDuration, int uid) { public RemoveUidRewriter(long bucketDuration, int[] uids) { mTemp = new NetworkStatsCollection(bucketDuration); mUid = uid; mUids = uids; } @Override Loading @@ -309,7 +314,7 @@ public class NetworkStatsRecorder { public void read(InputStream in) throws IOException { mTemp.read(in); mTemp.clearDirty(); mTemp.removeUid(mUid); mTemp.removeUids(mUids); } @Override Loading services/java/com/android/server/net/NetworkStatsService.java +63 −8 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import static android.Manifest.permission.MODIFY_NETWORK_ACCOUNTING; import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY; import static android.content.Intent.ACTION_SHUTDOWN; import static android.content.Intent.ACTION_UID_REMOVED; import static android.content.Intent.ACTION_USER_REMOVED; import static android.content.Intent.EXTRA_UID; import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE; Loading Loading @@ -76,6 +77,8 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.net.IConnectivityManager; import android.net.INetworkManagementEventObserver; import android.net.INetworkStatsService; Loading Loading @@ -112,6 +115,7 @@ import android.util.Slog; import android.util.SparseIntArray; import android.util.TrustedTime; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FileRotator; import com.android.internal.util.IndentingPrintWriter; import com.android.server.EventLogTags; Loading @@ -122,8 +126,10 @@ import java.io.File; import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; /** * Collect and persist detailed network statistics, and provide this data to Loading Loading @@ -322,6 +328,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED); mContext.registerReceiver(mRemovedReceiver, removedFilter, null, mHandler); // listen for user changes to clean stats final IntentFilter userFilter = new IntentFilter(ACTION_USER_REMOVED); mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler); // persist stats during clean shutdown final IntentFilter shutdownFilter = new IntentFilter(ACTION_SHUTDOWN); mContext.registerReceiver(mShutdownReceiver, shutdownFilter); Loading Loading @@ -739,11 +749,34 @@ public class NetworkStatsService extends INetworkStatsService.Stub { public void onReceive(Context context, Intent intent) { // on background handler thread, and UID_REMOVED is protected // broadcast. final int uid = intent.getIntExtra(EXTRA_UID, 0); final int uid = intent.getIntExtra(EXTRA_UID, -1); if (uid == -1) return; synchronized (mStatsLock) { mWakeLock.acquire(); try { removeUidLocked(uid); removeUidsLocked(uid); } finally { mWakeLock.release(); } } } }; private BroadcastReceiver mUserReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // On background handler thread, and USER_REMOVED is protected // broadcast. final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); if (userId == -1) return; synchronized (mStatsLock) { mWakeLock.acquire(); try { removeUserLocked(userId); } finally { mWakeLock.release(); } Loading Loading @@ -1034,16 +1067,38 @@ public class NetworkStatsService extends INetworkStatsService.Stub { /** * Clean up {@link #mUidRecorder} after UID is removed. */ private void removeUidLocked(int uid) { // perform one last poll before removing private void removeUidsLocked(int... uids) { if (LOGV) Slog.v(TAG, "removeUidsLocked() for UIDs " + Arrays.toString(uids)); // Perform one last poll before removing performPollLocked(FLAG_PERSIST_ALL); mUidRecorder.removeUidLocked(uid); mUidTagRecorder.removeUidLocked(uid); mUidRecorder.removeUidsLocked(uids); mUidTagRecorder.removeUidsLocked(uids); // clear kernel stats associated with UID // Clear kernel stats associated with UID for (int uid : uids) { resetKernelUidStats(uid); } } /** * Clean up {@link #mUidRecorder} after user is removed. */ private void removeUserLocked(int userId) { if (LOGV) Slog.v(TAG, "removeUserLocked() for userId=" + userId); // Build list of UIDs that we should clean up int[] uids = new int[0]; final List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications( PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_DISABLED_COMPONENTS); for (ApplicationInfo app : apps) { final int uid = UserHandle.getUid(userId, app.uid); uids = ArrayUtils.appendInt(uids, uid); } removeUidsLocked(uids); } @Override protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { Loading Loading
core/java/android/net/NetworkStats.java +3 −2 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.os.Parcelable; import android.os.SystemClock; import android.util.SparseBooleanArray; import com.android.internal.util.ArrayUtils; import com.android.internal.util.Objects; import java.io.CharArrayWriter; Loading Loading @@ -608,13 +609,13 @@ public class NetworkStats implements Parcelable { * Return all rows except those attributed to the requested UID; doesn't * mutate the original structure. */ public NetworkStats withoutUid(int uid) { public NetworkStats withoutUids(int[] uids) { final NetworkStats stats = new NetworkStats(elapsedRealtime, 10); Entry entry = new Entry(); for (int i = 0; i < size; i++) { entry = getValues(i, entry); if (entry.uid != uid) { if (!ArrayUtils.contains(uids, entry.uid)) { stats.addValues(entry); } } Loading
core/tests/coretests/src/android/net/NetworkStatsTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -287,7 +287,7 @@ public class NetworkStatsTest extends TestCase { .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L) .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 128L, 8L, 0L, 0L, 0L); final NetworkStats after = before.withoutUid(100); final NetworkStats after = before.withoutUids(new int[] { 100 }); assertEquals(6, before.size()); assertEquals(2, after.size()); assertValues(after, 0, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L); Loading
services/java/com/android/server/net/NetworkStatsCollection.java +3 −2 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.net.TrafficStats; import android.text.format.DateUtils; import android.util.AtomicFile; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FileRotator; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Objects; Loading Loading @@ -431,13 +432,13 @@ public class NetworkStatsCollection implements FileRotator.Reader { * moving any {@link NetworkStats#TAG_NONE} series to * {@link TrafficStats#UID_REMOVED}. */ public void removeUid(int uid) { public void removeUids(int[] uids) { final ArrayList<Key> knownKeys = Lists.newArrayList(); knownKeys.addAll(mStats.keySet()); // migrate all UID stats into special "removed" bucket for (Key key : knownKeys) { if (key.uid == uid) { if (ArrayUtils.contains(uids, key.uid)) { // only migrate combined TAG_NONE history if (key.tag == TAG_NONE) { final NetworkStatsHistory uidHistory = mStats.get(key); Loading
services/java/com/android/server/net/NetworkStatsRecorder.java +16 −11 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.ref.WeakReference; import java.util.Arrays; import java.util.HashSet; import java.util.Map; Loading Loading @@ -233,23 +234,27 @@ public class NetworkStatsRecorder { * Remove the given UID from all {@link FileRotator} history, migrating it * to {@link TrafficStats#UID_REMOVED}. */ public void removeUidLocked(int uid) { public void removeUidsLocked(int[] uids) { try { // process all existing data to migrate uid mRotator.rewriteAll(new RemoveUidRewriter(mBucketDuration, uid)); // Rewrite all persisted data to migrate UID stats mRotator.rewriteAll(new RemoveUidRewriter(mBucketDuration, uids)); } catch (IOException e) { Log.wtf(TAG, "problem removing UID " + uid, e); Log.wtf(TAG, "problem removing UIDs " + Arrays.toString(uids), e); recoverFromWtf(); } // clear UID from current stats snapshot // Remove any pending stats mPending.removeUids(uids); mSinceBoot.removeUids(uids); // Clear UID from current stats snapshot if (mLastSnapshot != null) { mLastSnapshot = mLastSnapshot.withoutUid(uid); mLastSnapshot = mLastSnapshot.withoutUids(uids); } final NetworkStatsCollection complete = mComplete != null ? mComplete.get() : null; if (complete != null) { complete.removeUid(uid); complete.removeUids(uids); } } Loading Loading @@ -293,11 +298,11 @@ public class NetworkStatsRecorder { */ public static class RemoveUidRewriter implements FileRotator.Rewriter { private final NetworkStatsCollection mTemp; private final int mUid; private final int[] mUids; public RemoveUidRewriter(long bucketDuration, int uid) { public RemoveUidRewriter(long bucketDuration, int[] uids) { mTemp = new NetworkStatsCollection(bucketDuration); mUid = uid; mUids = uids; } @Override Loading @@ -309,7 +314,7 @@ public class NetworkStatsRecorder { public void read(InputStream in) throws IOException { mTemp.read(in); mTemp.clearDirty(); mTemp.removeUid(mUid); mTemp.removeUids(mUids); } @Override Loading
services/java/com/android/server/net/NetworkStatsService.java +63 −8 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import static android.Manifest.permission.MODIFY_NETWORK_ACCOUNTING; import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY; import static android.content.Intent.ACTION_SHUTDOWN; import static android.content.Intent.ACTION_UID_REMOVED; import static android.content.Intent.ACTION_USER_REMOVED; import static android.content.Intent.EXTRA_UID; import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE; Loading Loading @@ -76,6 +77,8 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.net.IConnectivityManager; import android.net.INetworkManagementEventObserver; import android.net.INetworkStatsService; Loading Loading @@ -112,6 +115,7 @@ import android.util.Slog; import android.util.SparseIntArray; import android.util.TrustedTime; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FileRotator; import com.android.internal.util.IndentingPrintWriter; import com.android.server.EventLogTags; Loading @@ -122,8 +126,10 @@ import java.io.File; import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; /** * Collect and persist detailed network statistics, and provide this data to Loading Loading @@ -322,6 +328,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED); mContext.registerReceiver(mRemovedReceiver, removedFilter, null, mHandler); // listen for user changes to clean stats final IntentFilter userFilter = new IntentFilter(ACTION_USER_REMOVED); mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler); // persist stats during clean shutdown final IntentFilter shutdownFilter = new IntentFilter(ACTION_SHUTDOWN); mContext.registerReceiver(mShutdownReceiver, shutdownFilter); Loading Loading @@ -739,11 +749,34 @@ public class NetworkStatsService extends INetworkStatsService.Stub { public void onReceive(Context context, Intent intent) { // on background handler thread, and UID_REMOVED is protected // broadcast. final int uid = intent.getIntExtra(EXTRA_UID, 0); final int uid = intent.getIntExtra(EXTRA_UID, -1); if (uid == -1) return; synchronized (mStatsLock) { mWakeLock.acquire(); try { removeUidLocked(uid); removeUidsLocked(uid); } finally { mWakeLock.release(); } } } }; private BroadcastReceiver mUserReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // On background handler thread, and USER_REMOVED is protected // broadcast. final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); if (userId == -1) return; synchronized (mStatsLock) { mWakeLock.acquire(); try { removeUserLocked(userId); } finally { mWakeLock.release(); } Loading Loading @@ -1034,16 +1067,38 @@ public class NetworkStatsService extends INetworkStatsService.Stub { /** * Clean up {@link #mUidRecorder} after UID is removed. */ private void removeUidLocked(int uid) { // perform one last poll before removing private void removeUidsLocked(int... uids) { if (LOGV) Slog.v(TAG, "removeUidsLocked() for UIDs " + Arrays.toString(uids)); // Perform one last poll before removing performPollLocked(FLAG_PERSIST_ALL); mUidRecorder.removeUidLocked(uid); mUidTagRecorder.removeUidLocked(uid); mUidRecorder.removeUidsLocked(uids); mUidTagRecorder.removeUidsLocked(uids); // clear kernel stats associated with UID // Clear kernel stats associated with UID for (int uid : uids) { resetKernelUidStats(uid); } } /** * Clean up {@link #mUidRecorder} after user is removed. */ private void removeUserLocked(int userId) { if (LOGV) Slog.v(TAG, "removeUserLocked() for userId=" + userId); // Build list of UIDs that we should clean up int[] uids = new int[0]; final List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications( PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_DISABLED_COMPONENTS); for (ApplicationInfo app : apps) { final int uid = UserHandle.getUid(userId, app.uid); uids = ArrayUtils.appendInt(uids, uid); } removeUidsLocked(uids); } @Override protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { Loading