summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2011-06-19 01:08:12 -0700
committerJeff Sharkey <jsharkey@android.com>2011-06-19 01:08:12 -0700
commitb09540f33a6cabe50edec0ef32d0b1d0b0d96fff (patch)
treec185b8dd5cd0ad100803547c684c74c59346bc5c /services
parent1b5a2a96f793211bfbd39aa29cc41031dfa23950 (diff)
downloadframeworks_base-b09540f33a6cabe50edec0ef32d0b1d0b0d96fff.zip
frameworks_base-b09540f33a6cabe50edec0ef32d0b1d0b0d96fff.tar.gz
frameworks_base-b09540f33a6cabe50edec0ef32d0b1d0b0d96fff.tar.bz2
Handle removed UIDs in network stats and policy.
When UID_REMOVED, clean up any existing UID network policy so it doesn't linger for future apps. Also move any NetworkStatsHistory to special UID_REMOVED tracking bucket. Tests for new removal code. Also test detailed UID stats, including network changes to verify template matching logic. Bug: 4584212 Change-Id: I9faadf6b6f3830eb45d86c7f1980a27cdbcdb11e
Diffstat (limited to 'services')
-rw-r--r--services/java/com/android/server/net/NetworkPolicyManagerService.java28
-rw-r--r--services/java/com/android/server/net/NetworkStatsService.java69
-rw-r--r--services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java18
-rw-r--r--services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java182
4 files changed, 269 insertions, 28 deletions
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index ada9ba4..55d83a5 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -22,6 +22,8 @@ import static android.Manifest.permission.MANAGE_APP_TOKENS;
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.content.Intent.ACTION_UID_REMOVED;
+import static android.content.Intent.EXTRA_UID;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.TYPE_MOBILE;
import static android.net.NetworkPolicy.LIMIT_DISABLED;
@@ -247,9 +249,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mContext.registerReceiver(mScreenReceiver, screenFilter);
// watch for network interfaces to be claimed
- final IntentFilter ifaceFilter = new IntentFilter();
- ifaceFilter.addAction(CONNECTIVITY_ACTION);
- mContext.registerReceiver(mIfaceReceiver, ifaceFilter, CONNECTIVITY_INTERNAL, mHandler);
+ final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION);
+ mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler);
+
+ // listen for uid removal to clean policy
+ final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED);
+ mContext.registerReceiver(mRemovedReceiver, removedFilter, null, mHandler);
// listen for warning polling events; currently dispatched by
final IntentFilter statsFilter = new IntentFilter(ACTION_NETWORK_STATS_UPDATED);
@@ -312,6 +317,21 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
};
+ private BroadcastReceiver mRemovedReceiver = new BroadcastReceiver() {
+ @Override
+ 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);
+ synchronized (mRulesLock) {
+ // remove any policy and update rules to clean up
+ mUidPolicy.delete(uid);
+ updateRulesForUidLocked(uid);
+ writePolicyLocked();
+ }
+ }
+ };
+
/**
* Receiver that watches for {@link INetworkStatsService} updates, which we
* use to check against {@link NetworkPolicy#warningBytes}.
@@ -473,7 +493,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
* Receiver that watches for {@link IConnectivityManager} to claim network
* interfaces. Used to apply {@link NetworkPolicy} to matching networks.
*/
- private BroadcastReceiver mIfaceReceiver = new BroadcastReceiver() {
+ private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// on background handler thread, and verified CONNECTIVITY_INTERNAL
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index 54a806a..79612e3 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -19,11 +19,14 @@ package com.android.server.net;
import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
import static android.Manifest.permission.DUMP;
import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
-import static android.Manifest.permission.SHUTDOWN;
+import static android.content.Intent.ACTION_SHUTDOWN;
+import static android.content.Intent.ACTION_UID_REMOVED;
+import static android.content.Intent.EXTRA_UID;
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.net.TrafficStats.UID_REMOVED;
import static android.provider.Settings.Secure.NETSTATS_NETWORK_BUCKET_DURATION;
import static android.provider.Settings.Secure.NETSTATS_NETWORK_MAX_HISTORY;
import static android.provider.Settings.Secure.NETSTATS_PERSIST_THRESHOLD;
@@ -206,17 +209,20 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
// watch for network interfaces to be claimed
- final IntentFilter ifaceFilter = new IntentFilter();
- ifaceFilter.addAction(CONNECTIVITY_ACTION);
- mContext.registerReceiver(mIfaceReceiver, ifaceFilter, CONNECTIVITY_INTERNAL, mHandler);
+ final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION);
+ mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler);
// listen for periodic polling events
final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL);
mContext.registerReceiver(mPollReceiver, pollFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
+ // listen for uid removal to clean stats
+ final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED);
+ mContext.registerReceiver(mRemovedReceiver, removedFilter, null, mHandler);
+
// persist stats during clean shutdown
- final IntentFilter shutdownFilter = new IntentFilter(Intent.ACTION_SHUTDOWN);
- mContext.registerReceiver(mShutdownReceiver, shutdownFilter, SHUTDOWN, null);
+ final IntentFilter shutdownFilter = new IntentFilter(ACTION_SHUTDOWN);
+ mContext.registerReceiver(mShutdownReceiver, shutdownFilter);
try {
registerPollAlarmLocked();
@@ -226,8 +232,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
private void shutdownLocked() {
- mContext.unregisterReceiver(mIfaceReceiver);
+ mContext.unregisterReceiver(mConnReceiver);
mContext.unregisterReceiver(mPollReceiver);
+ mContext.unregisterReceiver(mRemovedReceiver);
mContext.unregisterReceiver(mShutdownReceiver);
writeNetworkStatsLocked();
@@ -352,7 +359,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
* interfaces. Used to associate {@link TelephonyManager#getSubscriberId()}
* with mobile interfaces.
*/
- private BroadcastReceiver mIfaceReceiver = new BroadcastReceiver() {
+ private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// on background handler thread, and verified CONNECTIVITY_INTERNAL
@@ -375,10 +382,22 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
};
+ private BroadcastReceiver mRemovedReceiver = new BroadcastReceiver() {
+ @Override
+ 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);
+ synchronized (mStatsLock) {
+ removeUidLocked(uid);
+ }
+ }
+ };
+
private BroadcastReceiver mShutdownReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- // verified SHUTDOWN permission above.
+ // SHUTDOWN is protected broadcast.
synchronized (mStatsLock) {
shutdownLocked();
}
@@ -545,6 +564,31 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
mLastUidPoll = uidStats;
}
+ /**
+ * Clean up {@link #mUidStats} after UID is removed.
+ */
+ private void removeUidLocked(int uid) {
+ ensureUidStatsLoadedLocked();
+
+ // migrate all UID stats into special "removed" bucket
+ for (NetworkIdentitySet ident : mUidStats.keySet()) {
+ final SparseArray<NetworkStatsHistory> uidStats = mUidStats.get(ident);
+ final NetworkStatsHistory uidHistory = uidStats.get(uid);
+ if (uidHistory != null) {
+ final NetworkStatsHistory removedHistory = findOrCreateUidStatsLocked(
+ ident, UID_REMOVED);
+ removedHistory.recordEntireHistory(uidHistory);
+ uidStats.remove(uid);
+ }
+ }
+
+ // TODO: push kernel event to wipe stats for UID, otherwise we risk
+ // picking them up again during next poll.
+
+ // since this was radical rewrite, push to disk
+ writeUidStatsLocked();
+ }
+
private NetworkStatsHistory findOrCreateNetworkStatsLocked(NetworkIdentitySet ident) {
final long bucketDuration = mSettings.getNetworkBucketDuration();
final NetworkStatsHistory existing = mNetworkStats.get(ident);
@@ -568,6 +612,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
private NetworkStatsHistory findOrCreateUidStatsLocked(NetworkIdentitySet ident, int uid) {
+ ensureUidStatsLoadedLocked();
+
// find bucket for identity first, then find uid
SparseArray<NetworkStatsHistory> uidStats = mUidStats.get(ident);
if (uidStats == null) {
@@ -734,6 +780,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private void writeUidStatsLocked() {
if (LOGV) Slog.v(TAG, "writeUidStatsLocked()");
+ if (!mUidStatsLoaded) {
+ Slog.w(TAG, "asked to write UID stats when not loaded; skipping");
+ return;
+ }
+
// TODO: consider duplicating stats and releasing lock while writing
FileOutputStream fos = null;
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index b62687a..07e5425 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -16,6 +16,8 @@
package com.android.server;
+import static android.content.Intent.ACTION_UID_REMOVED;
+import static android.content.Intent.EXTRA_UID;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.net.NetworkPolicyManager.POLICY_NONE;
@@ -386,6 +388,22 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
verifyAndReset();
}
+ public void testUidRemovedPolicyCleared() throws Exception {
+ // POLICY_REJECT should RULE_REJECT in background
+ expectRulesChanged(UID_A, RULE_REJECT_METERED);
+ replay();
+ mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
+ verifyAndReset();
+
+ // uninstall should clear RULE_REJECT
+ expectRulesChanged(UID_A, RULE_ALLOW_ALL);
+ replay();
+ final Intent intent = new Intent(ACTION_UID_REMOVED);
+ intent.putExtra(EXTRA_UID, UID_A);
+ mServiceContext.sendBroadcast(intent);
+ verifyAndReset();
+ }
+
private static long parseTime(String time) {
final Time result = new Time();
result.parse3339(time);
diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
index 1d2634c..2c6dbbf 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
@@ -16,11 +16,16 @@
package com.android.server;
+import static android.content.Intent.ACTION_UID_REMOVED;
+import static android.content.Intent.EXTRA_UID;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
+import static android.net.ConnectivityManager.TYPE_MOBILE;
import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
+import static android.net.NetworkTemplate.MATCH_MOBILE_ALL;
import static android.net.NetworkTemplate.MATCH_WIFI;
+import static android.net.TrafficStats.UID_REMOVED;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
@@ -46,6 +51,7 @@ import android.net.NetworkStats;
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
import android.os.INetworkManagementService;
+import android.telephony.TelephonyManager;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.util.TrustedTime;
@@ -67,10 +73,16 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
private static final String TEST_IFACE = "test0";
private static final long TEST_START = 1194220800000L;
+ private static final String IMSI_1 = "310004";
+ private static final String IMSI_2 = "310260";
+
private static NetworkTemplate sTemplateWifi = new NetworkTemplate(MATCH_WIFI, null);
+ private static NetworkTemplate sTemplateImsi1 = new NetworkTemplate(MATCH_MOBILE_ALL, IMSI_1);
+ private static NetworkTemplate sTemplateImsi2 = new NetworkTemplate(MATCH_MOBILE_ALL, IMSI_2);
- private static final int TEST_UID_1 = 1001;
- private static final int TEST_UID_2 = 1002;
+ private static final int TEST_UID_RED = 1001;
+ private static final int TEST_UID_BLUE = 1002;
+ private static final int TEST_UID_GREEN = 1003;
private BroadcastInterceptingContext mServiceContext;
private File mStatsDir;
@@ -121,13 +133,15 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
mNetManager = null;
mAlarmManager = null;
mTime = null;
+ mSettings = null;
+ mConnManager = null;
mService = null;
super.tearDown();
}
- public void testSummaryStatsWifi() throws Exception {
+ public void testNetworkStatsWifi() throws Exception {
long elapsedRealtime = 0;
// pretend that wifi network comes online; service should ask about full
@@ -202,16 +216,16 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
.addEntry(TEST_IFACE, UID_ALL, TAG_NONE, 1024L, 2048L));
expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 2)
- .addEntry(TEST_IFACE, TEST_UID_1, TAG_NONE, 512L, 256L)
- .addEntry(TEST_IFACE, TEST_UID_2, TAG_NONE, 128L, 128L));
+ .addEntry(TEST_IFACE, TEST_UID_RED, TAG_NONE, 512L, 256L)
+ .addEntry(TEST_IFACE, TEST_UID_BLUE, TAG_NONE, 128L, 128L));
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
assertNetworkTotal(sTemplateWifi, 1024L, 2048L);
- assertUidTotal(sTemplateWifi, TEST_UID_1, 512L, 256L);
- assertUidTotal(sTemplateWifi, TEST_UID_2, 128L, 128L);
+ assertUidTotal(sTemplateWifi, TEST_UID_RED, 512L, 256L);
+ assertUidTotal(sTemplateWifi, TEST_UID_BLUE, 128L, 128L);
verifyAndReset();
// graceful shutdown system, which should trigger persist of stats, and
@@ -236,8 +250,8 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
// after systemReady(), we should have historical stats loaded again
assertNetworkTotal(sTemplateWifi, 1024L, 2048L);
- assertUidTotal(sTemplateWifi, TEST_UID_1, 512L, 256L);
- assertUidTotal(sTemplateWifi, TEST_UID_2, 128L, 128L);
+ assertUidTotal(sTemplateWifi, TEST_UID_RED, 512L, 256L);
+ assertUidTotal(sTemplateWifi, TEST_UID_BLUE, 128L, 128L);
verifyAndReset();
}
@@ -301,6 +315,135 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
}
+ public void testUidStatsAcrossNetworks() throws Exception {
+ long elapsedRealtime = 0;
+
+ // pretend first mobile network comes online
+ expectTime(TEST_START + elapsedRealtime);
+ expectDefaultSettings();
+ expectNetworkState(buildMobile3gState(IMSI_1));
+ expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
+
+ replay();
+ mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
+ verifyAndReset();
+
+ // create some traffic on first network
+ elapsedRealtime += HOUR_IN_MILLIS;
+ expectTime(TEST_START + elapsedRealtime);
+ expectDefaultSettings();
+ expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
+ .addEntry(TEST_IFACE, UID_ALL, TAG_NONE, 2048L, 512L));
+ expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 3)
+ .addEntry(TEST_IFACE, TEST_UID_RED, TAG_NONE, 1024L, 0L)
+ .addEntry(TEST_IFACE, TEST_UID_RED, 0xF00D, 512L, 512L)
+ .addEntry(TEST_IFACE, TEST_UID_BLUE, TAG_NONE, 512L, 0L));
+
+ replay();
+ mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
+
+ // verify service recorded history
+ assertNetworkTotal(sTemplateImsi1, 2048L, 512L);
+ assertNetworkTotal(sTemplateWifi, 0L, 0L);
+ assertUidTotal(sTemplateImsi1, TEST_UID_RED, 1536L, 512L);
+ assertUidTotal(sTemplateImsi1, TEST_UID_BLUE, 512L, 0L);
+ verifyAndReset();
+
+ // now switch networks; this also tests that we're okay with interfaces
+ // disappearing, to verify we don't count backwards.
+ elapsedRealtime += HOUR_IN_MILLIS;
+ expectTime(TEST_START + elapsedRealtime);
+ expectDefaultSettings();
+ expectNetworkState(buildMobile3gState(IMSI_2));
+ expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
+ expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
+
+ replay();
+ mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
+ mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
+ verifyAndReset();
+
+ // create traffic on second network
+ elapsedRealtime += HOUR_IN_MILLIS;
+ expectTime(TEST_START + elapsedRealtime);
+ expectDefaultSettings();
+ expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
+ .addEntry(TEST_IFACE, UID_ALL, TAG_NONE, 128L, 1024L));
+ expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1)
+ .addEntry(TEST_IFACE, TEST_UID_BLUE, TAG_NONE, 128L, 1024L));
+
+ replay();
+ mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
+
+ // verify original history still intact
+ assertNetworkTotal(sTemplateImsi1, 2048L, 512L);
+ assertUidTotal(sTemplateImsi1, TEST_UID_RED, 1536L, 512L);
+ assertUidTotal(sTemplateImsi1, TEST_UID_BLUE, 512L, 0L);
+
+ // and verify new history also recorded under different template, which
+ // verifies that we didn't cross the streams.
+ assertNetworkTotal(sTemplateImsi2, 128L, 1024L);
+ assertNetworkTotal(sTemplateWifi, 0L, 0L);
+ assertUidTotal(sTemplateImsi2, TEST_UID_BLUE, 128L, 1024L);
+ verifyAndReset();
+
+ }
+
+ public void testUidRemovedIsMoved() throws Exception {
+ long elapsedRealtime = 0;
+
+ // pretend that network comes online
+ expectTime(TEST_START + elapsedRealtime);
+ expectDefaultSettings();
+ expectNetworkState(buildWifiState());
+ expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
+
+ replay();
+ mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
+ verifyAndReset();
+
+ // create some traffic
+ elapsedRealtime += HOUR_IN_MILLIS;
+ expectTime(TEST_START + elapsedRealtime);
+ expectDefaultSettings();
+ expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
+ .addEntry(TEST_IFACE, UID_ALL, TAG_NONE, 4128L, 544L));
+ expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1)
+ .addEntry(TEST_IFACE, TEST_UID_RED, TAG_NONE, 16L, 16L)
+ .addEntry(TEST_IFACE, TEST_UID_BLUE, TAG_NONE, 4096L, 512L)
+ .addEntry(TEST_IFACE, TEST_UID_GREEN, TAG_NONE, 16L, 16L));
+
+ replay();
+ mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
+
+ // verify service recorded history
+ assertNetworkTotal(sTemplateWifi, 4128L, 544L);
+ assertUidTotal(sTemplateWifi, TEST_UID_RED, 16L, 16L);
+ assertUidTotal(sTemplateWifi, TEST_UID_BLUE, 4096L, 512L);
+ assertUidTotal(sTemplateWifi, TEST_UID_GREEN, 16L, 16L);
+ verifyAndReset();
+
+ // now pretend two UIDs are uninstalled, which should migrate stats to
+ // special "removed" bucket.
+ expectDefaultSettings();
+ replay();
+ final Intent intent = new Intent(ACTION_UID_REMOVED);
+ intent.putExtra(EXTRA_UID, TEST_UID_BLUE);
+ mServiceContext.sendBroadcast(intent);
+ intent.putExtra(EXTRA_UID, TEST_UID_RED);
+ mServiceContext.sendBroadcast(intent);
+
+ // existing uid and total should remain unchanged; but removed UID
+ // should be gone completely.
+ assertNetworkTotal(sTemplateWifi, 4128L, 544L);
+ assertUidTotal(sTemplateWifi, TEST_UID_RED, 0L, 0L);
+ assertUidTotal(sTemplateWifi, TEST_UID_BLUE, 0L, 0L);
+ assertUidTotal(sTemplateWifi, TEST_UID_GREEN, 16L, 16L);
+ assertUidTotal(sTemplateWifi, UID_REMOVED, 4112L, 528L);
+ verifyAndReset();
+
+ }
+
private void assertNetworkTotal(NetworkTemplate template, long rx, long tx) {
final NetworkStatsHistory history = mService.getHistoryForNetwork(template);
final long[] total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null);
@@ -360,14 +503,14 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
}
private void assertStatsFilesExist(boolean exist) {
- final File summaryFile = new File(mStatsDir, "netstats.bin");
- final File detailFile = new File(mStatsDir, "netstats_uid.bin");
+ final File networkFile = new File(mStatsDir, "netstats.bin");
+ final File uidFile = new File(mStatsDir, "netstats_uid.bin");
if (exist) {
- assertTrue(summaryFile.exists());
- assertTrue(detailFile.exists());
+ assertTrue(networkFile.exists());
+ assertTrue(uidFile.exists());
} else {
- assertFalse(summaryFile.exists());
- assertFalse(detailFile.exists());
+ assertFalse(networkFile.exists());
+ assertFalse(uidFile.exists());
}
}
@@ -379,6 +522,15 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
return new NetworkState(info, prop, null);
}
+ private static NetworkState buildMobile3gState(String subscriberId) {
+ final NetworkInfo info = new NetworkInfo(
+ TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UMTS, null, null);
+ info.setDetailedState(DetailedState.CONNECTED, null, null);
+ final LinkProperties prop = new LinkProperties();
+ prop.setInterfaceName(TEST_IFACE);
+ return new NetworkState(info, prop, null, subscriberId);
+ }
+
private static NetworkStats buildEmptyStats(long elapsedRealtime) {
return new NetworkStats(elapsedRealtime, 0);
}