diff options
author | Jeff Sharkey <jsharkey@android.com> | 2011-06-19 01:12:01 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-06-19 01:12:01 -0700 |
commit | 75a0e9c0f076093368ca50ac7e905a48af919f8b (patch) | |
tree | 33b75956d59e71858468b12117d2ca306bc38148 /services | |
parent | 13e7d3fa07f9f1aee3f0e8b4e118dccfe89558ee (diff) | |
parent | b09540f33a6cabe50edec0ef32d0b1d0b0d96fff (diff) | |
download | frameworks_base-75a0e9c0f076093368ca50ac7e905a48af919f8b.zip frameworks_base-75a0e9c0f076093368ca50ac7e905a48af919f8b.tar.gz frameworks_base-75a0e9c0f076093368ca50ac7e905a48af919f8b.tar.bz2 |
Merge "Handle removed UIDs in network stats and policy."
Diffstat (limited to 'services')
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); } |