From 9e441af03a632f94200ab788576ac02b8beb8865 Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Tue, 5 Jan 2021 00:41:07 +0000 Subject: [PATCH] Update meteredness of cellular networks for tests. This would allow us to run both metered and unmetered networkpolicy related tests when the device is on a cellular network. Bug: 165343126 Test: atest CtsHostsideNetworkTests:HostsideRestrictBackgroundNetworkTests Test: atest CtsHostsideNetworkTests:HostsideNetworkCallbackTests Ignore-AOSP-First: Handling merge-conflict Change-Id: Id70856dffc920e74bda28583dba4dd851a832397 --- .../MeterednessConfigurationRule.java | 15 ++- .../cts/net/hostside/NetworkCallbackTest.java | 13 +-- .../net/hostside/NetworkPolicyTestUtils.java | 109 +++++++++++++++--- .../cts/net/hostside/app2/MyService.java | 5 +- 4 files changed, 105 insertions(+), 37 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java index 8fadf9e295..5c99c679c8 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java @@ -15,21 +15,20 @@ */ package com.android.cts.net.hostside; -import static com.android.cts.net.hostside.NetworkPolicyTestUtils.resetMeteredNetwork; -import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setupMeteredNetwork; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setupActiveNetworkMeteredness; import static com.android.cts.net.hostside.Property.METERED_NETWORK; import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; import android.util.ArraySet; -import android.util.Pair; import com.android.compatibility.common.util.BeforeAfterRule; +import com.android.compatibility.common.util.ThrowingRunnable; import org.junit.runner.Description; import org.junit.runners.model.Statement; public class MeterednessConfigurationRule extends BeforeAfterRule { - private Pair mSsidAndInitialMeteredness; + private ThrowingRunnable mMeterednessResetter; @Override public void onBefore(Statement base, Description description) throws Throwable { @@ -48,13 +47,13 @@ public class MeterednessConfigurationRule extends BeforeAfterRule { } public void configureNetworkMeteredness(boolean metered) throws Exception { - mSsidAndInitialMeteredness = setupMeteredNetwork(metered); + mMeterednessResetter = setupActiveNetworkMeteredness(metered); } public void resetNetworkMeteredness() throws Exception { - if (mSsidAndInitialMeteredness != null) { - resetMeteredNetwork(mSsidAndInitialMeteredness.first, - mSsidAndInitialMeteredness.second); + if (mMeterednessResetter != null) { + mMeterednessResetter.run(); + mMeterednessResetter = null; } } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java index 2ac29e77ff..955317bbf6 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java @@ -17,16 +17,13 @@ package com.android.cts.net.hostside; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; + import static com.android.cts.net.hostside.NetworkPolicyTestUtils.canChangeActiveNetworkMeteredness; import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground; -import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isActiveNetworkMetered; import static com.android.cts.net.hostside.Property.BATTERY_SAVER_MODE; import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; @@ -186,7 +183,7 @@ public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCa public void setUp() throws Exception { super.setUp(); - assumeTrue(isActiveNetworkMetered(true) || canChangeActiveNetworkMeteredness()); + assumeTrue(canChangeActiveNetworkMeteredness()); registerBroadcastReceiver(); @@ -198,13 +195,13 @@ public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCa setBatterySaverMode(false); setRestrictBackground(false); - // Make wifi a metered network. + // Mark network as metered. mMeterednessConfiguration.configureNetworkMeteredness(true); // Register callback registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); - // Once the wifi is marked as metered, the wifi will reconnect. Wait for onAvailable() - // callback to ensure wifi is connected before the test and store the default network. + // Wait for onAvailable() callback to ensure network is available before the test + // and store the default network. mNetwork = mTestNetworkCallback.expectAvailableCallbackAndGetNetwork(); // Check that the network is metered. mTestNetworkCallback.expectCapabilitiesCallbackEventually(mNetwork, diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java index 06b8dfe17d..e8d1a98461 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java @@ -20,14 +20,17 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLE import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; +import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static com.android.compatibility.common.util.SystemUtil.runShellCommand; import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TAG; +import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TEST_PKG; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -42,15 +45,20 @@ import android.net.NetworkCapabilities; import android.net.wifi.WifiManager; import android.os.Process; import android.os.UserHandle; +import android.telephony.SubscriptionManager; +import android.telephony.SubscriptionPlan; import android.text.TextUtils; import android.util.Log; -import android.util.Pair; import androidx.test.platform.app.InstrumentationRegistry; import com.android.compatibility.common.util.AppStandbyUtils; import com.android.compatibility.common.util.BatteryUtils; +import com.android.compatibility.common.util.ThrowingRunnable; +import java.time.Period; +import java.time.ZonedDateTime; +import java.util.Arrays; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -60,6 +68,7 @@ public class NetworkPolicyTestUtils { private static ConnectivityManager mCm; private static WifiManager mWm; + private static SubscriptionManager mSm; private static Boolean mBatterySaverSupported; private static Boolean mDataSaverSupported; @@ -142,16 +151,40 @@ public class NetworkPolicyTestUtils { } public static boolean canChangeActiveNetworkMeteredness() { - final Network activeNetwork = getConnectivityManager().getActiveNetwork(); - final NetworkCapabilities networkCapabilities - = getConnectivityManager().getNetworkCapabilities(activeNetwork); - return networkCapabilities.hasTransport(TRANSPORT_WIFI); + final NetworkCapabilities networkCapabilities = getActiveNetworkCapabilities(); + return networkCapabilities.hasTransport(TRANSPORT_WIFI) + || networkCapabilities.hasTransport(TRANSPORT_CELLULAR); } - public static Pair setupMeteredNetwork(boolean metered) throws Exception { + /** + * Updates the meteredness of the active network. Right now we can only change meteredness + * of either Wifi or cellular network, so if the active network is not either of these, this + * will throw an exception. + * + * @return a {@link ThrowingRunnable} object that can used to reset the meteredness change + * made by this method. + */ + public static ThrowingRunnable setupActiveNetworkMeteredness(boolean metered) throws Exception { if (isActiveNetworkMetered(metered)) { return null; } + final NetworkCapabilities networkCapabilities = getActiveNetworkCapabilities(); + if (networkCapabilities.hasTransport(TRANSPORT_WIFI)) { + final String ssid = getWifiSsid(); + setWifiMeteredStatus(ssid, metered); + return () -> setWifiMeteredStatus(ssid, !metered); + } else if (networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) { + final int subId = SubscriptionManager.getActiveDataSubscriptionId(); + setCellularMeteredStatus(subId, metered); + return () -> setCellularMeteredStatus(subId, !metered); + } else { + // Right now, we don't have a way to change meteredness of networks other + // than Wi-Fi or Cellular, so just throw an exception. + throw new IllegalStateException("Can't change meteredness of current active network"); + } + } + + private static String getWifiSsid() { final boolean isLocationEnabled = isLocationEnabled(); try { if (!isLocationEnabled) { @@ -159,8 +192,7 @@ public class NetworkPolicyTestUtils { } final String ssid = unquoteSSID(getWifiManager().getConnectionInfo().getSSID()); assertNotEquals(WifiManager.UNKNOWN_SSID, ssid); - setWifiMeteredStatus(ssid, metered); - return Pair.create(ssid, !metered); + return ssid; } finally { // Reset the location enabled state if (!isLocationEnabled) { @@ -169,11 +201,13 @@ public class NetworkPolicyTestUtils { } } - public static void resetMeteredNetwork(String ssid, boolean metered) throws Exception { - setWifiMeteredStatus(ssid, metered); + private static NetworkCapabilities getActiveNetworkCapabilities() { + final Network activeNetwork = getConnectivityManager().getActiveNetwork(); + assertNotNull("No active network available", activeNetwork); + return getConnectivityManager().getNetworkCapabilities(activeNetwork); } - public static void setWifiMeteredStatus(String ssid, boolean metered) throws Exception { + private static void setWifiMeteredStatus(String ssid, boolean metered) throws Exception { assertFalse("SSID should not be empty", TextUtils.isEmpty(ssid)); final String cmd = "cmd netpolicy set metered-network " + ssid + " " + metered; executeShellCommand(cmd); @@ -181,15 +215,29 @@ public class NetworkPolicyTestUtils { assertActiveNetworkMetered(metered); } - public static void assertWifiMeteredStatus(String ssid, boolean expectedMeteredStatus) { + private static void assertWifiMeteredStatus(String ssid, boolean expectedMeteredStatus) { final String result = executeShellCommand("cmd netpolicy list wifi-networks"); final String expectedLine = ssid + ";" + expectedMeteredStatus; assertTrue("Expected line: " + expectedLine + "; Actual result: " + result, result.contains(expectedLine)); } + private static void setCellularMeteredStatus(int subId, boolean metered) throws Exception { + setSubPlanOwner(subId, TEST_PKG); + try { + getSubscriptionManager().setSubscriptionPlans(subId, + Arrays.asList(buildValidSubscriptionPlan(System.currentTimeMillis()))); + final boolean unmeteredOverride = !metered; + getSubscriptionManager().setSubscriptionOverrideUnmetered(subId, unmeteredOverride, + /*timeoutMillis=*/ 0); + assertActiveNetworkMetered(metered); + } finally { + setSubPlanOwner(subId, null); + } + } + // Copied from cts/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java - public static void assertActiveNetworkMetered(boolean expectedMeteredStatus) throws Exception { + private static void assertActiveNetworkMetered(boolean expectedMeteredStatus) throws Exception { final CountDownLatch latch = new CountDownLatch(1); final NetworkCallback networkCallback = new NetworkCallback() { @Override @@ -204,12 +252,29 @@ public class NetworkPolicyTestUtils { // with the current setting. Therefore, if the setting has already been changed, // this method will return right away, and if not it will wait for the setting to change. getConnectivityManager().registerDefaultNetworkCallback(networkCallback); - if (!latch.await(TIMEOUT_CHANGE_METEREDNESS_MS, TimeUnit.MILLISECONDS)) { - fail("Timed out waiting for active network metered status to change to " - + expectedMeteredStatus + " ; network = " - + getConnectivityManager().getActiveNetwork()); + try { + if (!latch.await(TIMEOUT_CHANGE_METEREDNESS_MS, TimeUnit.MILLISECONDS)) { + fail("Timed out waiting for active network metered status to change to " + + expectedMeteredStatus + "; network = " + + getConnectivityManager().getActiveNetwork()); + } + } finally { + getConnectivityManager().unregisterNetworkCallback(networkCallback); } - getConnectivityManager().unregisterNetworkCallback(networkCallback); + } + + private static void setSubPlanOwner(int subId, String packageName) { + executeShellCommand("cmd netpolicy set sub-plan-owner " + subId + " " + packageName); + } + + private static SubscriptionPlan buildValidSubscriptionPlan(long dataUsageTime) { + return SubscriptionPlan.Builder + .createRecurring(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"), + Period.ofMonths(1)) + .setTitle("CTS") + .setDataLimit(1_000_000_000, SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED) + .setDataUsage(500_000_000, dataUsageTime) + .build(); } public static void setRestrictBackground(boolean enabled) { @@ -288,6 +353,14 @@ public class NetworkPolicyTestUtils { return mWm; } + public static SubscriptionManager getSubscriptionManager() { + if (mSm == null) { + mSm = (SubscriptionManager) getContext().getSystemService( + Context.TELEPHONY_SUBSCRIPTION_SERVICE); + } + return mSm; + } + public static Context getContext() { return getInstrumentation().getContext(); } diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java index a263490a9a..9e10d41d06 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java @@ -140,7 +140,7 @@ public class MyService extends Service { } } }; - mCm.registerNetworkCallback(makeWifiNetworkRequest(), mNetworkCallback); + mCm.registerNetworkCallback(makeNetworkRequest(), mNetworkCallback); try { cb.asBinder().linkToDeath(() -> unregisterNetworkCallback(), 0); } catch (RemoteException e) { @@ -165,9 +165,8 @@ public class MyService extends Service { } }; - private NetworkRequest makeWifiNetworkRequest() { + private NetworkRequest makeNetworkRequest() { return new NetworkRequest.Builder() - .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .build(); }