Merge "Add test for NetworkCapabilities.Builder.withoutDefaultCapabilities"
diff --git a/framework/src/android/net/ConnectivityDiagnosticsManager.java b/framework/src/android/net/ConnectivityDiagnosticsManager.java
index 3598ebc..dcc8a5e 100644
--- a/framework/src/android/net/ConnectivityDiagnosticsManager.java
+++ b/framework/src/android/net/ConnectivityDiagnosticsManager.java
@@ -713,7 +713,9 @@
* <p>Callbacks registered by apps not meeting the above criteria will not be invoked.
*
* <p>If a registering app loses its relevant permissions, any callbacks it registered will
- * silently stop receiving callbacks.
+ * silently stop receiving callbacks. Note that registering apps must also have location
+ * permissions to receive callbacks as some Networks may be location-bound (such as WiFi
+ * networks).
*
* <p>Each register() call <b>MUST</b> use a ConnectivityDiagnosticsCallback instance that is
* not currently registered. If a ConnectivityDiagnosticsCallback instance is registered with
diff --git a/framework/src/android/net/NetworkRequest.java b/framework/src/android/net/NetworkRequest.java
index dd88c5a..e6a96ef 100644
--- a/framework/src/android/net/NetworkRequest.java
+++ b/framework/src/android/net/NetworkRequest.java
@@ -200,8 +200,9 @@
private final NetworkCapabilities mNetworkCapabilities;
- // A boolean that represents the user modified NOT_VCN_MANAGED capability.
- private boolean mModifiedNotVcnManaged = false;
+ // A boolean that represents whether the NOT_VCN_MANAGED capability should be deduced when
+ // the NetworkRequest object is built.
+ private boolean mShouldDeduceNotVcnManaged = true;
/**
* Default constructor for Builder.
@@ -223,7 +224,7 @@
// If the caller constructed the builder from a request, it means the user
// might explicitly want the capabilities from the request. Thus, the NOT_VCN_MANAGED
// capabilities should not be touched later.
- mModifiedNotVcnManaged = true;
+ mShouldDeduceNotVcnManaged = false;
}
/**
@@ -254,7 +255,7 @@
public Builder addCapability(@NetworkCapabilities.NetCapability int capability) {
mNetworkCapabilities.addCapability(capability);
if (capability == NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED) {
- mModifiedNotVcnManaged = true;
+ mShouldDeduceNotVcnManaged = false;
}
return this;
}
@@ -268,7 +269,7 @@
public Builder removeCapability(@NetworkCapabilities.NetCapability int capability) {
mNetworkCapabilities.removeCapability(capability);
if (capability == NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED) {
- mModifiedNotVcnManaged = true;
+ mShouldDeduceNotVcnManaged = false;
}
return this;
}
@@ -352,7 +353,7 @@
mNetworkCapabilities.clearAll();
// If the caller explicitly clear all capabilities, the NOT_VCN_MANAGED capabilities
// should not be add back later.
- mModifiedNotVcnManaged = true;
+ mShouldDeduceNotVcnManaged = false;
return this;
}
@@ -453,6 +454,9 @@
throw new IllegalArgumentException("A MatchAllNetworkSpecifier is not permitted");
}
mNetworkCapabilities.setNetworkSpecifier(networkSpecifier);
+ // Do not touch NOT_VCN_MANAGED if the caller needs to access to a very specific
+ // Network.
+ mShouldDeduceNotVcnManaged = false;
return this;
}
@@ -486,12 +490,13 @@
* {@link #VCN_SUPPORTED_CAPABILITIES}, add the NET_CAPABILITY_NOT_VCN_MANAGED to
* allow the callers automatically utilize VCN networks if available.
* 2. For the requests that explicitly add or remove NET_CAPABILITY_NOT_VCN_MANAGED,
+ * or has clear intention of tracking specific network,
* do not alter them to allow user fire request that suits their need.
*
* @hide
*/
private void deduceNotVcnManagedCapability(final NetworkCapabilities nc) {
- if (mModifiedNotVcnManaged) return;
+ if (!mShouldDeduceNotVcnManaged) return;
for (final int cap : nc.getCapabilities()) {
if (!VCN_SUPPORTED_CAPABILITIES.contains(cap)) return;
}
diff --git a/framework/src/android/net/apf/ApfCapabilities.java b/framework/src/android/net/apf/ApfCapabilities.java
index 85b2471..663c1b3 100644
--- a/framework/src/android/net/apf/ApfCapabilities.java
+++ b/framework/src/android/net/apf/ApfCapabilities.java
@@ -131,43 +131,21 @@
* @return Whether the APF Filter in the device should filter out IEEE 802.3 Frames.
*/
public static boolean getApfDrop8023Frames() {
- // TODO(b/183076074): remove reading resources from system resources
+ // TODO: deprecate/remove this method (now unused in the platform), as the resource was
+ // moved to NetworkStack.
final Resources systemRes = Resources.getSystem();
final int id = systemRes.getIdentifier("config_apfDrop802_3Frames", "bool", "android");
return systemRes.getBoolean(id);
}
/**
- * @return Whether the APF Filter in the device should filter out IEEE 802.3 Frames.
- * @hide
- */
- public static boolean getApfDrop8023Frames(@NonNull Context context) {
- final ConnectivityResources res = getResources(context);
- // TODO(b/183076074): use R.bool.config_apfDrop802_3Frames directly
- final int id = res.get().getIdentifier("config_apfDrop802_3Frames", "bool",
- res.getResourcesContext().getPackageName());
- return res.get().getBoolean(id);
- }
-
- /**
* @return An array of denylisted EtherType, packets with EtherTypes within it will be dropped.
*/
public static @NonNull int[] getApfEtherTypeBlackList() {
- // TODO(b/183076074): remove reading resources from system resources
+ // TODO: deprecate/remove this method (now unused in the platform), as the resource was
+ // moved to NetworkStack.
final Resources systemRes = Resources.getSystem();
final int id = systemRes.getIdentifier("config_apfEthTypeBlackList", "array", "android");
return systemRes.getIntArray(id);
}
-
- /**
- * @return An array of denylisted EtherType, packets with EtherTypes within it will be dropped.
- * @hide
- */
- public static @NonNull int[] getApfEtherTypeDenyList(@NonNull Context context) {
- final ConnectivityResources res = getResources(context);
- // TODO(b/183076074): use R.array.config_apfEthTypeDenyList directly
- final int id = res.get().getIdentifier("config_apfEthTypeDenyList", "array",
- res.getResourcesContext().getPackageName());
- return res.get().getIntArray(id);
- }
}
diff --git a/service/ServiceConnectivityResources/res/values/config.xml b/service/ServiceConnectivityResources/res/values/config.xml
index 9ff2a22..078a9eb 100644
--- a/service/ServiceConnectivityResources/res/values/config.xml
+++ b/service/ServiceConnectivityResources/res/values/config.xml
@@ -52,22 +52,6 @@
<item>12,60000</item><!-- mobile_cbs -->
</string-array>
- <!-- Whether the APF Filter in the device should filter out IEEE 802.3 Frames
- Those frames are identified by the field Eth-type having values
- less than 0x600 -->
- <bool translatable="false" name="config_apfDrop802_3Frames">true</bool>
-
- <!-- An array of Denylisted EtherType, packets with EtherTypes within this array
- will be dropped
- TODO: need to put proper values, these are for testing purposes only -->
- <integer-array translatable="false" name="config_apfEthTypeDenyList">
- <item>0x88A2</item>
- <item>0x88A4</item>
- <item>0x88B8</item>
- <item>0x88CD</item>
- <item>0x88E3</item>
- </integer-array>
-
<!-- Default supported concurrent socket keepalive slots per transport type, used by
ConnectivityManager.createSocketKeepalive() for calculating the number of keepalive
offload slots that should be reserved for privileged access. This string array should be
diff --git a/service/ServiceConnectivityResources/res/values/overlayable.xml b/service/ServiceConnectivityResources/res/values/overlayable.xml
index 717d08e..f0f4ae8 100644
--- a/service/ServiceConnectivityResources/res/values/overlayable.xml
+++ b/service/ServiceConnectivityResources/res/values/overlayable.xml
@@ -21,8 +21,6 @@
<item type="string" name="config_networkCaptivePortalServerUrl"/>
<item type="integer" name="config_networkTransitionTimeout"/>
<item type="array" name="config_wakeonlan_supported_interfaces"/>
- <item type="bool" name="config_apfDrop802_3Frames"/>
- <item type="array" name="config_apfEthTypeDenyList"/>
<item type="integer" name="config_networkMeteredMultipathPreference"/>
<item type="array" name="config_networkSupportedKeepaliveCount"/>
<item type="integer" name="config_networkAvoidBadWifi"/>
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index b2e2943..842ad62 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -9175,6 +9175,34 @@
return results;
}
+ private boolean hasLocationPermission(String packageName, int uid) {
+ // LocationPermissionChecker#checkLocationPermission can throw SecurityException if the uid
+ // and package name don't match. Throwing on the CS thread is not acceptable, so wrap the
+ // call in a try-catch.
+ try {
+ if (!mLocationPermissionChecker.checkLocationPermission(
+ packageName, null /* featureId */, uid, null /* message */)) {
+ return false;
+ }
+ } catch (SecurityException e) {
+ return false;
+ }
+
+ return true;
+ }
+
+ private boolean ownsVpnRunningOverNetwork(int uid, Network network) {
+ for (NetworkAgentInfo virtual : mNetworkAgentInfos) {
+ if (virtual.supportsUnderlyingNetworks()
+ && virtual.networkCapabilities.getOwnerUid() == uid
+ && CollectionUtils.contains(virtual.declaredUnderlyingNetworks, network)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
@VisibleForTesting
boolean checkConnectivityDiagnosticsPermissions(
int callbackPid, int callbackUid, NetworkAgentInfo nai, String callbackPackageName) {
@@ -9182,29 +9210,14 @@
return true;
}
- // LocationPermissionChecker#checkLocationPermission can throw SecurityException if the uid
- // and package name don't match. Throwing on the CS thread is not acceptable, so wrap the
- // call in a try-catch.
- try {
- if (!mLocationPermissionChecker.checkLocationPermission(
- callbackPackageName, null /* featureId */, callbackUid, null /* message */)) {
- return false;
- }
- } catch (SecurityException e) {
+ // Administrator UIDs also contains the Owner UID
+ final int[] administratorUids = nai.networkCapabilities.getAdministratorUids();
+ if (!CollectionUtils.contains(administratorUids, callbackUid)
+ && !ownsVpnRunningOverNetwork(callbackUid, nai.network)) {
return false;
}
- for (NetworkAgentInfo virtual : mNetworkAgentInfos) {
- if (virtual.supportsUnderlyingNetworks()
- && virtual.networkCapabilities.getOwnerUid() == callbackUid
- && CollectionUtils.contains(virtual.declaredUnderlyingNetworks, nai.network)) {
- return true;
- }
- }
-
- // Administrator UIDs also contains the Owner UID
- final int[] administratorUids = nai.networkCapabilities.getAdministratorUids();
- return CollectionUtils.contains(administratorUids, callbackUid);
+ return hasLocationPermission(callbackPackageName, callbackUid);
}
@Override
diff --git a/tests/common/java/android/net/apf/ApfCapabilitiesTest.java b/tests/common/java/android/net/apf/ApfCapabilitiesTest.java
index d50406f..88996d9 100644
--- a/tests/common/java/android/net/apf/ApfCapabilitiesTest.java
+++ b/tests/common/java/android/net/apf/ApfCapabilitiesTest.java
@@ -18,6 +18,7 @@
import static com.android.testutils.ParcelUtils.assertParcelSane;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
@@ -25,12 +26,17 @@
import static org.junit.Assert.assertTrue;
import android.content.Context;
+import android.os.Build;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -39,6 +45,9 @@
@RunWith(AndroidJUnit4.class)
@SmallTest
public class ApfCapabilitiesTest {
+ @Rule
+ public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule();
+
private Context mContext;
@Before
@@ -85,6 +94,17 @@
assertEquals(shouldDrop8023Frames, actual);
}
+ @Test @IgnoreUpTo(Build.VERSION_CODES.R)
+ public void testGetApfDrop8023Frames_S() {
+ // IpClient does not call getApfDrop8023Frames() since S, so any customization of the return
+ // value on S+ is a configuration error as it will not be used by IpClient.
+ assertTrue("android.R.bool.config_apfDrop802_3Frames has been modified to false, but "
+ + "starting from S its value is not used by IpClient. If the modification is "
+ + "intentional, use a runtime resource overlay for the NetworkStack package to "
+ + "overlay com.android.networkstack.R.bool.config_apfDrop802_3Frames instead.",
+ ApfCapabilities.getApfDrop8023Frames());
+ }
+
@Test
public void testGetApfEtherTypeBlackList() {
// Get com.android.internal.R.array.config_apfEthTypeBlackList. The test cannot directly
@@ -96,4 +116,17 @@
assertNotNull(actual);
assertTrue(Arrays.equals(blacklistedEtherTypeArray, actual));
}
+
+ @Test @IgnoreUpTo(Build.VERSION_CODES.R)
+ public void testGetApfEtherTypeBlackList_S() {
+ // IpClient does not call getApfEtherTypeBlackList() since S, so any customization of the
+ // return value on S+ is a configuration error as it will not be used by IpClient.
+ assertArrayEquals("android.R.array.config_apfEthTypeBlackList has been modified, but "
+ + "starting from S its value is not used by IpClient. If the modification "
+ + "is intentional, use a runtime resource overlay for the NetworkStack "
+ + "package to overlay "
+ + "com.android.networkstack.R.array.config_apfEthTypeDenyList instead.",
+ new int[] { 0x88a2, 0x88a4, 0x88b8, 0x88cd, 0x88e3 },
+ ApfCapabilities.getApfEtherTypeBlackList());
+ }
}
diff --git a/tests/unit/java/android/net/NetworkTemplateTest.kt b/tests/unit/java/android/net/NetworkTemplateTest.kt
index ab6b2f4..cb39a0c 100644
--- a/tests/unit/java/android/net/NetworkTemplateTest.kt
+++ b/tests/unit/java/android/net/NetworkTemplateTest.kt
@@ -40,7 +40,7 @@
import android.net.NetworkTemplate.SUBSCRIBER_ID_MATCH_RULE_EXACT
import android.net.NetworkTemplate.buildTemplateWifi
import android.net.NetworkTemplate.buildTemplateWifiWildcard
-import android.net.NetworkTemplate.buildTemplateCarrier
+import android.net.NetworkTemplate.buildTemplateCarrierMetered
import android.net.NetworkTemplate.buildTemplateMobileWithRatType
import android.telephony.TelephonyManager
import com.android.testutils.assertParcelSane
@@ -73,11 +73,12 @@
type: Int,
subscriberId: String? = null,
ssid: String? = null,
- oemManaged: Int = OEM_NONE
+ oemManaged: Int = OEM_NONE,
+ metered: Boolean = true
): NetworkStateSnapshot {
val lp = LinkProperties()
val caps = NetworkCapabilities().apply {
- setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false)
+ setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, !metered)
setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true)
setSSID(ssid)
setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID,
@@ -167,25 +168,38 @@
}
@Test
- fun testCarrierMatches() {
- val templateCarrierImsi1 = buildTemplateCarrier(TEST_IMSI1)
+ fun testCarrierMeteredMatches() {
+ val templateCarrierImsi1Metered = buildTemplateCarrierMetered(TEST_IMSI1)
- val identMobile1 = buildNetworkIdentity(mockContext, buildMobileNetworkState(TEST_IMSI1),
- false, TelephonyManager.NETWORK_TYPE_UMTS)
- val identMobile2 = buildNetworkIdentity(mockContext, buildMobileNetworkState(TEST_IMSI2),
- false, TelephonyManager.NETWORK_TYPE_UMTS)
- val identWifiSsid1 = buildNetworkIdentity(
- mockContext, buildWifiNetworkState(null, TEST_SSID1), true, 0)
- val identCarrierWifiImsi1 = buildNetworkIdentity(
- mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_SSID1), true, 0)
- val identCarrierWifiImsi2 = buildNetworkIdentity(
- mockContext, buildWifiNetworkState(TEST_IMSI2, TEST_SSID1), true, 0)
+ val mobileImsi1 = buildMobileNetworkState(TEST_IMSI1)
+ val mobileImsi1Unmetered = buildNetworkState(TYPE_MOBILE, TEST_IMSI1, null /* ssid */,
+ OEM_NONE, false /* metered */)
+ val mobileImsi2 = buildMobileNetworkState(TEST_IMSI2)
+ val wifiSsid1 = buildWifiNetworkState(null /* subscriberId */, TEST_SSID1)
+ val wifiImsi1Ssid1 = buildWifiNetworkState(TEST_IMSI1, TEST_SSID1)
+ val wifiImsi1Ssid1Unmetered = buildNetworkState(TYPE_WIFI, TEST_IMSI1, TEST_SSID1,
+ OEM_NONE, false /* metered */)
- templateCarrierImsi1.assertMatches(identCarrierWifiImsi1)
- templateCarrierImsi1.assertDoesNotMatch(identCarrierWifiImsi2)
- templateCarrierImsi1.assertDoesNotMatch(identWifiSsid1)
- templateCarrierImsi1.assertMatches(identMobile1)
- templateCarrierImsi1.assertDoesNotMatch(identMobile2)
+ val identMobileImsi1Metered = buildNetworkIdentity(mockContext,
+ mobileImsi1, false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
+ val identMobileImsi1Unmetered = buildNetworkIdentity(mockContext,
+ mobileImsi1Unmetered, false /* defaultNetwork */,
+ TelephonyManager.NETWORK_TYPE_UMTS)
+ val identMobileImsi2Metered = buildNetworkIdentity(mockContext,
+ mobileImsi2, false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
+ val identWifiSsid1Metered = buildNetworkIdentity(
+ mockContext, wifiSsid1, true /* defaultNetwork */, 0 /* subType */)
+ val identCarrierWifiImsi1Metered = buildNetworkIdentity(
+ mockContext, wifiImsi1Ssid1, true /* defaultNetwork */, 0 /* subType */)
+ val identCarrierWifiImsi1NonMetered = buildNetworkIdentity(mockContext,
+ wifiImsi1Ssid1Unmetered, true /* defaultNetwork */, 0 /* subType */)
+
+ templateCarrierImsi1Metered.assertMatches(identMobileImsi1Metered)
+ templateCarrierImsi1Metered.assertDoesNotMatch(identMobileImsi1Unmetered)
+ templateCarrierImsi1Metered.assertDoesNotMatch(identMobileImsi2Metered)
+ templateCarrierImsi1Metered.assertDoesNotMatch(identWifiSsid1Metered)
+ templateCarrierImsi1Metered.assertMatches(identCarrierWifiImsi1Metered)
+ templateCarrierImsi1Metered.assertDoesNotMatch(identCarrierWifiImsi1NonMetered)
}
@Test
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index 41458f1..1b4f836 100644
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -9743,28 +9743,32 @@
@Test
public void testCheckConnectivityDiagnosticsPermissionsWrongUidPackageName() throws Exception {
- final NetworkAgentInfo naiWithoutUid = fakeMobileNai(new NetworkCapabilities());
+ final int wrongUid = Process.myUid() + 1;
+
+ final NetworkCapabilities nc = new NetworkCapabilities();
+ nc.setAdministratorUids(new int[] {wrongUid});
+ final NetworkAgentInfo naiWithUid = fakeMobileNai(nc);
mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED);
assertFalse(
"Mismatched uid/package name should not pass the location permission check",
mService.checkConnectivityDiagnosticsPermissions(
- Process.myPid() + 1, Process.myUid() + 1, naiWithoutUid,
- mContext.getOpPackageName()));
+ Process.myPid() + 1, wrongUid, naiWithUid, mContext.getOpPackageName()));
}
@Test
public void testCheckConnectivityDiagnosticsPermissionsNoLocationPermission() throws Exception {
- final NetworkAgentInfo naiWithoutUid = fakeMobileNai(new NetworkCapabilities());
+ final NetworkCapabilities nc = new NetworkCapabilities();
+ nc.setAdministratorUids(new int[] {Process.myUid()});
+ final NetworkAgentInfo naiWithUid = fakeMobileNai(nc);
mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED);
assertFalse(
"ACCESS_FINE_LOCATION permission necessary for Connectivity Diagnostics",
mService.checkConnectivityDiagnosticsPermissions(
- Process.myPid(), Process.myUid(), naiWithoutUid,
- mContext.getOpPackageName()));
+ Process.myPid(), Process.myUid(), naiWithUid, mContext.getOpPackageName()));
}
@Test
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java b/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java
index f3ae9b0..93599f3 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java
@@ -43,6 +43,7 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.frameworks.tests.net.R;
+import com.android.internal.util.test.FsUtil;
import libcore.io.IoUtils;
import libcore.io.Streams;
@@ -71,7 +72,7 @@
public void setUp() throws Exception {
mTestProc = new File(InstrumentationRegistry.getContext().getFilesDir(), "proc");
if (mTestProc.exists()) {
- IoUtils.deleteContents(mTestProc);
+ FsUtil.deleteContents(mTestProc);
}
// The libandroid_servers which have the native method is not available to
@@ -87,7 +88,7 @@
mFactory = null;
if (mTestProc.exists()) {
- IoUtils.deleteContents(mTestProc);
+ FsUtil.deleteContents(mTestProc);
}
}
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
index fe2985c..0ba5f7d 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -112,13 +112,12 @@
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.test.BroadcastInterceptingContext;
+import com.android.internal.util.test.FsUtil;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
import com.android.testutils.HandlerUtils;
import com.android.testutils.TestableNetworkStatsProviderBinder;
-import libcore.io.IoUtils;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
@@ -152,6 +151,8 @@
private static final String TEST_SSID = "AndroidAP";
private static NetworkTemplate sTemplateWifi = buildTemplateWifi(TEST_SSID);
+ private static NetworkTemplate sTemplateCarrierWifi1 =
+ buildTemplateWifi(NetworkTemplate.WIFI_NETWORKID_ALL, IMSI_1);
private static NetworkTemplate sTemplateImsi1 = buildTemplateMobileAll(IMSI_1);
private static NetworkTemplate sTemplateImsi2 = buildTemplateMobileAll(IMSI_2);
@@ -213,7 +214,7 @@
mServiceContext = new MockContext(context);
mStatsDir = context.getFilesDir();
if (mStatsDir.exists()) {
- IoUtils.deleteContents(mStatsDir);
+ FsUtil.deleteContents(mStatsDir);
}
PowerManager powerManager = (PowerManager) mServiceContext.getSystemService(
@@ -283,7 +284,7 @@
@After
public void tearDown() throws Exception {
- IoUtils.deleteContents(mStatsDir);
+ FsUtil.deleteContents(mStatsDir);
mServiceContext = null;
mStatsDir = null;
@@ -297,45 +298,82 @@
mHandlerThread.quitSafely();
}
- @Test
- public void testNetworkStatsWifi() throws Exception {
+ private void initWifiStats(NetworkStateSnapshot snapshot) throws Exception {
// pretend that wifi network comes online; service should ask about full
// network state, and poll any existing interfaces before updating.
expectDefaultSettings();
- NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {snapshot};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
+ }
- // verify service has empty history for wifi
+ private void incrementWifiStats(long durationMillis, String iface,
+ long rxb, long rxp, long txb, long txp) throws Exception {
+ incrementCurrentTime(durationMillis);
+ expectDefaultSettings();
+ expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
+ .insertEntry(iface, rxb, rxp, txb, txp));
+ expectNetworkStatsUidDetail(buildEmptyStats());
+ forcePollAndWaitForIdle();
+ }
+
+ @Test
+ public void testNetworkStatsCarrierWifi() throws Exception {
+ initWifiStats(buildWifiState(true, TEST_IFACE, IMSI_1));
+ // verify service has empty history for carrier merged wifi and non-carrier wifi
+ assertNetworkTotal(sTemplateCarrierWifi1, 0L, 0L, 0L, 0L, 0);
assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
// modify some number on wifi, and trigger poll event
- incrementCurrentTime(HOUR_IN_MILLIS);
- expectDefaultSettings();
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .insertEntry(TEST_IFACE, 1024L, 1L, 2048L, 2L));
- expectNetworkStatsUidDetail(buildEmptyStats());
- forcePollAndWaitForIdle();
+ incrementWifiStats(HOUR_IN_MILLIS, TEST_IFACE, 1024L, 1L, 2048L, 2L);
// verify service recorded history
- assertNetworkTotal(sTemplateWifi, 1024L, 1L, 2048L, 2L, 0);
+ assertNetworkTotal(sTemplateCarrierWifi1, 1024L, 1L, 2048L, 2L, 0);
+
+ // verify service recorded history for wifi with SSID filter
+ assertNetworkTotal(sTemplateWifi, 1024L, 1L, 2048L, 2L, 0);
// and bump forward again, with counters going higher. this is
// important, since polling should correctly subtract last snapshot.
- incrementCurrentTime(DAY_IN_MILLIS);
- expectDefaultSettings();
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .insertEntry(TEST_IFACE, 4096L, 4L, 8192L, 8L));
- expectNetworkStatsUidDetail(buildEmptyStats());
- forcePollAndWaitForIdle();
+ incrementWifiStats(DAY_IN_MILLIS, TEST_IFACE, 4096L, 4L, 8192L, 8L);
+
+ // verify service recorded history
+ assertNetworkTotal(sTemplateCarrierWifi1, 4096L, 4L, 8192L, 8L, 0);
+ // verify service recorded history for wifi with SSID filter
+ assertNetworkTotal(sTemplateWifi, 4096L, 4L, 8192L, 8L, 0);
+ }
+
+ @Test
+ public void testNetworkStatsNonCarrierWifi() throws Exception {
+ initWifiStats(buildWifiState());
+
+ // verify service has empty history for wifi
+ assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
+ // verify service has empty history for carrier merged wifi
+ assertNetworkTotal(sTemplateCarrierWifi1, 0L, 0L, 0L, 0L, 0);
+
+ // modify some number on wifi, and trigger poll event
+ incrementWifiStats(HOUR_IN_MILLIS, TEST_IFACE, 1024L, 1L, 2048L, 2L);
+
+ // verify service recorded history
+ assertNetworkTotal(sTemplateWifi, 1024L, 1L, 2048L, 2L, 0);
+ // verify service has empty history for carrier wifi since current network is non carrier
+ // wifi
+ assertNetworkTotal(sTemplateCarrierWifi1, 0L, 0L, 0L, 0L, 0);
+
+ // and bump forward again, with counters going higher. this is
+ // important, since polling should correctly subtract last snapshot.
+ incrementWifiStats(DAY_IN_MILLIS, TEST_IFACE, 4096L, 4L, 8192L, 8L);
// verify service recorded history
assertNetworkTotal(sTemplateWifi, 4096L, 4L, 8192L, 8L, 0);
-
+ // verify service has empty history for carrier wifi since current network is non carrier
+ // wifi
+ assertNetworkTotal(sTemplateCarrierWifi1, 0L, 0L, 0L, 0L, 0);
}
@Test
@@ -1662,10 +1700,15 @@
}
private static NetworkStateSnapshot buildWifiState() {
- return buildWifiState(false, TEST_IFACE);
+ return buildWifiState(false, TEST_IFACE, null);
}
private static NetworkStateSnapshot buildWifiState(boolean isMetered, @NonNull String iface) {
+ return buildWifiState(isMetered, iface, null);
+ }
+
+ private static NetworkStateSnapshot buildWifiState(boolean isMetered, @NonNull String iface,
+ String subscriberId) {
final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(iface);
final NetworkCapabilities capabilities = new NetworkCapabilities();
@@ -1673,7 +1716,7 @@
capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true);
capabilities.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
capabilities.setSSID(TEST_SSID);
- return new NetworkStateSnapshot(WIFI_NETWORK, capabilities, prop, null, TYPE_WIFI);
+ return new NetworkStateSnapshot(WIFI_NETWORK, capabilities, prop, subscriberId, TYPE_WIFI);
}
private static NetworkStateSnapshot buildMobile3gState(String subscriberId) {