am c3e3311c: Merge "Migrate network stats from removed users." into jb-mr1-dev

* commit 'c3e3311c050f47a229e1b49f1fdf685669d79d53':
  Migrate network stats from removed users.
This commit is contained in:
Jeff Sharkey
2012-09-20 06:09:01 -07:00
committed by Android Git Automerger
4 changed files with 85 additions and 23 deletions

View File

@@ -21,6 +21,7 @@ import android.os.Parcelable;
import android.os.SystemClock; import android.os.SystemClock;
import android.util.SparseBooleanArray; import android.util.SparseBooleanArray;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.Objects; import com.android.internal.util.Objects;
import java.io.CharArrayWriter; import java.io.CharArrayWriter;
@@ -608,13 +609,13 @@ public class NetworkStats implements Parcelable {
* Return all rows except those attributed to the requested UID; doesn't * Return all rows except those attributed to the requested UID; doesn't
* mutate the original structure. * mutate the original structure.
*/ */
public NetworkStats withoutUid(int uid) { public NetworkStats withoutUids(int[] uids) {
final NetworkStats stats = new NetworkStats(elapsedRealtime, 10); final NetworkStats stats = new NetworkStats(elapsedRealtime, 10);
Entry entry = new Entry(); Entry entry = new Entry();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
entry = getValues(i, entry); entry = getValues(i, entry);
if (entry.uid != uid) { if (!ArrayUtils.contains(uids, entry.uid)) {
stats.addValues(entry); stats.addValues(entry);
} }
} }

View File

@@ -31,6 +31,7 @@ import android.net.TrafficStats;
import android.text.format.DateUtils; import android.text.format.DateUtils;
import android.util.AtomicFile; import android.util.AtomicFile;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FileRotator; import com.android.internal.util.FileRotator;
import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Objects; import com.android.internal.util.Objects;
@@ -431,13 +432,13 @@ public class NetworkStatsCollection implements FileRotator.Reader {
* moving any {@link NetworkStats#TAG_NONE} series to * moving any {@link NetworkStats#TAG_NONE} series to
* {@link TrafficStats#UID_REMOVED}. * {@link TrafficStats#UID_REMOVED}.
*/ */
public void removeUid(int uid) { public void removeUids(int[] uids) {
final ArrayList<Key> knownKeys = Lists.newArrayList(); final ArrayList<Key> knownKeys = Lists.newArrayList();
knownKeys.addAll(mStats.keySet()); knownKeys.addAll(mStats.keySet());
// migrate all UID stats into special "removed" bucket // migrate all UID stats into special "removed" bucket
for (Key key : knownKeys) { for (Key key : knownKeys) {
if (key.uid == uid) { if (ArrayUtils.contains(uids, key.uid)) {
// only migrate combined TAG_NONE history // only migrate combined TAG_NONE history
if (key.tag == TAG_NONE) { if (key.tag == TAG_NONE) {
final NetworkStatsHistory uidHistory = mStats.get(key); final NetworkStatsHistory uidHistory = mStats.get(key);

View File

@@ -42,6 +42,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
@@ -233,23 +234,27 @@ public class NetworkStatsRecorder {
* Remove the given UID from all {@link FileRotator} history, migrating it * Remove the given UID from all {@link FileRotator} history, migrating it
* to {@link TrafficStats#UID_REMOVED}. * to {@link TrafficStats#UID_REMOVED}.
*/ */
public void removeUidLocked(int uid) { public void removeUidsLocked(int[] uids) {
try { try {
// process all existing data to migrate uid // Rewrite all persisted data to migrate UID stats
mRotator.rewriteAll(new RemoveUidRewriter(mBucketDuration, uid)); mRotator.rewriteAll(new RemoveUidRewriter(mBucketDuration, uids));
} catch (IOException e) { } catch (IOException e) {
Log.wtf(TAG, "problem removing UID " + uid, e); Log.wtf(TAG, "problem removing UIDs " + Arrays.toString(uids), e);
recoverFromWtf(); 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) { if (mLastSnapshot != null) {
mLastSnapshot = mLastSnapshot.withoutUid(uid); mLastSnapshot = mLastSnapshot.withoutUids(uids);
} }
final NetworkStatsCollection complete = mComplete != null ? mComplete.get() : null; final NetworkStatsCollection complete = mComplete != null ? mComplete.get() : null;
if (complete != null) { if (complete != null) {
complete.removeUid(uid); complete.removeUids(uids);
} }
} }
@@ -293,11 +298,11 @@ public class NetworkStatsRecorder {
*/ */
public static class RemoveUidRewriter implements FileRotator.Rewriter { public static class RemoveUidRewriter implements FileRotator.Rewriter {
private final NetworkStatsCollection mTemp; 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); mTemp = new NetworkStatsCollection(bucketDuration);
mUid = uid; mUids = uids;
} }
@Override @Override
@@ -309,7 +314,7 @@ public class NetworkStatsRecorder {
public void read(InputStream in) throws IOException { public void read(InputStream in) throws IOException {
mTemp.read(in); mTemp.read(in);
mTemp.clearDirty(); mTemp.clearDirty();
mTemp.removeUid(mUid); mTemp.removeUids(mUids);
} }
@Override @Override

View File

@@ -23,6 +23,7 @@ import static android.Manifest.permission.MODIFY_NETWORK_ACCOUNTING;
import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY; import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
import static android.content.Intent.ACTION_SHUTDOWN; import static android.content.Intent.ACTION_SHUTDOWN;
import static android.content.Intent.ACTION_UID_REMOVED; 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.content.Intent.EXTRA_UID;
import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED; import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
@@ -76,6 +77,8 @@ import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.IConnectivityManager; import android.net.IConnectivityManager;
import android.net.INetworkManagementEventObserver; import android.net.INetworkManagementEventObserver;
import android.net.INetworkStatsService; import android.net.INetworkStatsService;
@@ -112,6 +115,7 @@ import android.util.Slog;
import android.util.SparseIntArray; import android.util.SparseIntArray;
import android.util.TrustedTime; import android.util.TrustedTime;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FileRotator; import com.android.internal.util.FileRotator;
import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.IndentingPrintWriter;
import com.android.server.EventLogTags; import com.android.server.EventLogTags;
@@ -122,8 +126,10 @@ import java.io.File;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
/** /**
* Collect and persist detailed network statistics, and provide this data to * Collect and persist detailed network statistics, and provide this data to
@@ -322,6 +328,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED); final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED);
mContext.registerReceiver(mRemovedReceiver, removedFilter, null, mHandler); 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 // persist stats during clean shutdown
final IntentFilter shutdownFilter = new IntentFilter(ACTION_SHUTDOWN); final IntentFilter shutdownFilter = new IntentFilter(ACTION_SHUTDOWN);
mContext.registerReceiver(mShutdownReceiver, shutdownFilter); mContext.registerReceiver(mShutdownReceiver, shutdownFilter);
@@ -739,11 +749,34 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
// on background handler thread, and UID_REMOVED is protected // on background handler thread, and UID_REMOVED is protected
// broadcast. // broadcast.
final int uid = intent.getIntExtra(EXTRA_UID, 0);
final int uid = intent.getIntExtra(EXTRA_UID, -1);
if (uid == -1) return;
synchronized (mStatsLock) { synchronized (mStatsLock) {
mWakeLock.acquire(); mWakeLock.acquire();
try { 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 { } finally {
mWakeLock.release(); mWakeLock.release();
} }
@@ -1034,15 +1067,37 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
/** /**
* Clean up {@link #mUidRecorder} after UID is removed. * Clean up {@link #mUidRecorder} after UID is removed.
*/ */
private void removeUidLocked(int uid) { private void removeUidsLocked(int... uids) {
// perform one last poll before removing if (LOGV) Slog.v(TAG, "removeUidsLocked() for UIDs " + Arrays.toString(uids));
// Perform one last poll before removing
performPollLocked(FLAG_PERSIST_ALL); performPollLocked(FLAG_PERSIST_ALL);
mUidRecorder.removeUidLocked(uid); mUidRecorder.removeUidsLocked(uids);
mUidTagRecorder.removeUidLocked(uid); mUidTagRecorder.removeUidsLocked(uids);
// clear kernel stats associated with UID // Clear kernel stats associated with UID
resetKernelUidStats(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 @Override