summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-01-07 22:05:37 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-01-07 22:05:37 +0000
commit81025012dc7a102176449d269186de91e984c594 (patch)
tree922e8108e83e90657b3070c66407827ca9e731dc
parent99cb88b1c7be7c1b12da45316656546ced4cde26 (diff)
parentfea58811da97306a4364a83088bf10ae877100a3 (diff)
downloadcts-android13-qpr2-b-s1-release.tar.gz
Change-Id: Ia74ad141050c67928486cd10de198eada7ff9db1
-rw-r--r--tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java326
-rw-r--r--tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java186
-rw-r--r--tests/JobScheduler/src/android/jobscheduler/cts/NetworkingHelper.java432
-rw-r--r--tests/tests/telephony/current/src/android/telephony/cts/VisualVoicemailServiceTest.java3
4 files changed, 470 insertions, 477 deletions
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
index 00d7517d263..7b0d2616b4a 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
@@ -18,48 +18,25 @@ package android.jobscheduler.cts;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
-import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
-import static com.android.compatibility.common.util.TestUtils.waitUntil;
-
-import android.Manifest;
import android.annotation.TargetApi;
import android.app.job.JobInfo;
import android.app.job.JobParameters;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.content.pm.PackageManager;
-import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
-import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
import android.platform.test.annotations.RequiresDevice;
import android.provider.Settings;
import android.util.Log;
import com.android.compatibility.common.util.AppStandbyUtils;
import com.android.compatibility.common.util.BatteryUtils;
-import com.android.compatibility.common.util.CallbackAsserter;
-import com.android.compatibility.common.util.ShellIdentityUtils;
import com.android.compatibility.common.util.SystemUtil;
-import junit.framework.AssertionFailedError;
-
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
/**
* Schedules jobs with the {@link android.app.job.JobScheduler} that have network connectivity
* constraints.
@@ -70,18 +47,13 @@ import java.util.regex.Pattern;
@RequiresDevice // Emulators don't always have access to wifi/network
public class ConnectivityConstraintTest extends BaseJobSchedulerTest {
private static final String TAG = "ConnectivityConstraintTest";
- private static final String RESTRICT_BACKGROUND_GET_CMD =
- "cmd netpolicy get restrict-background";
- private static final String RESTRICT_BACKGROUND_ON_CMD =
- "cmd netpolicy set restrict-background true";
- private static final String RESTRICT_BACKGROUND_OFF_CMD =
- "cmd netpolicy set restrict-background false";
/** Unique identifier for the job scheduled by this suite of tests. */
public static final int CONNECTIVITY_JOB_ID = ConnectivityConstraintTest.class.hashCode();
/** Wait this long before timing out the test. */
private static final long DEFAULT_TIMEOUT_MILLIS = 30000L; // 30 seconds.
+ private NetworkingHelper mNetworkingHelper;
private WifiManager mWifiManager;
private ConnectivityManager mCm;
@@ -89,21 +61,8 @@ public class ConnectivityConstraintTest extends BaseJobSchedulerTest {
private boolean mHasWifi;
/** Whether the device running these tests supports telephony. */
private boolean mHasTelephony;
- /** Whether the device running these tests supports ethernet. */
- private boolean mHasEthernet;
- /** Track whether WiFi was enabled in case we turn it off. */
- private boolean mInitialWiFiState;
- /** Track initial WiFi metered state. */
- private String mInitialWiFiMeteredState;
- private String mInitialWiFiSSID;
- /** Track whether restrict background policy was enabled in case we turn it off. */
- private boolean mInitialRestrictBackground;
- /** Track whether airplane mode was enabled in case we toggle it. */
- private boolean mInitialAirplaneMode;
/** Track whether the restricted bucket was enabled in case we toggle it. */
private String mInitialRestrictedBucketEnabled;
- /** Track the location mode in case we change it. */
- private String mInitialLocationMode;
private JobInfo.Builder mBuilder;
@@ -115,30 +74,20 @@ public class ConnectivityConstraintTest extends BaseJobSchedulerTest {
mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+ mNetworkingHelper = new NetworkingHelper(getInstrumentation(), getContext());
PackageManager packageManager = mContext.getPackageManager();
mHasWifi = packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI);
mHasTelephony = packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
- mHasEthernet = packageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET);
mBuilder = new JobInfo.Builder(CONNECTIVITY_JOB_ID, kJobServiceComponent);
- mInitialLocationMode = Settings.Secure.getString(mContext.getContentResolver(),
- Settings.Secure.LOCATION_MODE);
if (mHasWifi) {
- mInitialWiFiState = mWifiManager.isWifiEnabled();
- ensureSavedWifiNetwork(mWifiManager);
- setWifiState(true, mCm, mWifiManager);
- mInitialWiFiSSID = getWifiSSID();
- mInitialWiFiMeteredState = getWifiMeteredStatus(mInitialWiFiSSID);
+ mNetworkingHelper.ensureSavedWifiNetwork();
}
- mInitialRestrictBackground = SystemUtil
- .runShellCommand(getInstrumentation(), RESTRICT_BACKGROUND_GET_CMD)
- .contains("enabled");
mInitialRestrictedBucketEnabled = Settings.Global.getString(mContext.getContentResolver(),
Settings.Global.ENABLE_RESTRICTED_BUCKET);
setDataSaverEnabled(false);
- mInitialAirplaneMode = isAirplaneModeOn();
- setAirplaneMode(false);
+ mNetworkingHelper.setAllNetworksEnabled(true);
// Force the test app out of the never bucket.
SystemUtil.runShellCommand("am set-standby-bucket "
+ TestAppInterface.TEST_APP_PACKAGE + " rare");
@@ -153,31 +102,12 @@ public class ConnectivityConstraintTest extends BaseJobSchedulerTest {
BatteryUtils.runDumpsysBatteryReset();
- // Restore initial restrict background data usage policy
- setDataSaverEnabled(mInitialRestrictBackground);
-
// Restore initial restricted bucket setting.
Settings.Global.putString(mContext.getContentResolver(),
Settings.Global.ENABLE_RESTRICTED_BUCKET, mInitialRestrictedBucketEnabled);
// Ensure that we leave WiFi in its previous state.
- if (mHasWifi) {
- setWifiMeteredState(mInitialWiFiSSID, mInitialWiFiMeteredState);
- if (mWifiManager.isWifiEnabled() != mInitialWiFiState) {
- try {
- setWifiState(mInitialWiFiState, mCm, mWifiManager);
- } catch (AssertionFailedError e) {
- // Don't fail the test just because wifi state wasn't set in tearDown.
- Log.e(TAG, "Failed to return wifi state to " + mInitialWiFiState, e);
- }
- }
- }
-
- // Restore initial airplane mode status. Do it after setting wifi in case wifi was
- // originally metered.
- setAirplaneMode(mInitialAirplaneMode);
-
- setLocationMode(mInitialLocationMode);
+ mNetworkingHelper.tearDown();
super.tearDown();
}
@@ -585,7 +515,7 @@ public class ConnectivityConstraintTest extends BaseJobSchedulerTest {
}
public void testJobParametersNetwork() throws Exception {
- setAirplaneMode(false);
+ mNetworkingHelper.setAllNetworksEnabled(true);
// Everything good.
final NetworkRequest nr = new NetworkRequest.Builder()
@@ -608,7 +538,7 @@ public class ConnectivityConstraintTest extends BaseJobSchedulerTest {
if (!hasEthernetConnection()) {
// Deadline passed with no network satisfied.
- setAirplaneMode(true);
+ mNetworkingHelper.setAllNetworksEnabled(false);
ji = mBuilder
.setRequiredNetwork(nr)
.setOverrideDeadline(0)
@@ -624,7 +554,7 @@ public class ConnectivityConstraintTest extends BaseJobSchedulerTest {
}
// No network requested
- setAirplaneMode(false);
+ mNetworkingHelper.setAllNetworksEnabled(true);
ji = mBuilder.setRequiredNetwork(null).build();
kTestEnvironment.setExpectedExecutions(1);
mJobScheduler.schedule(ji);
@@ -875,149 +805,25 @@ public class ConnectivityConstraintTest extends BaseJobSchedulerTest {
}
private boolean hasEthernetConnection() {
- if (!mHasEthernet) return false;
- Network[] networks = mCm.getAllNetworks();
- for (Network network : networks) {
- if (mCm.getNetworkCapabilities(network).hasTransport(TRANSPORT_ETHERNET)) {
- return true;
- }
- }
- return false;
- }
-
- private String unquoteSSID(String ssid) {
- // SSID is returned surrounded by quotes if it can be decoded as UTF-8.
- // Otherwise it's guaranteed not to start with a quote.
- if (ssid.charAt(0) == '"') {
- return ssid.substring(1, ssid.length() - 1);
- } else {
- return ssid;
- }
- }
-
- private String getWifiSSID() throws Exception {
- // Location needs to be enabled to get the WiFi information.
- setLocationMode(String.valueOf(Settings.Secure.LOCATION_MODE_ON));
- final AtomicReference<String> ssid = new AtomicReference<>();
- SystemUtil.runWithShellPermissionIdentity(() -> {
- ssid.set(mWifiManager.getConnectionInfo().getSSID());
- }, Manifest.permission.ACCESS_FINE_LOCATION);
- return unquoteSSID(ssid.get());
- }
-
- private void setLocationMode(String mode) throws Exception {
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.LOCATION_MODE, mode);
- final LocationManager locationManager = mContext.getSystemService(LocationManager.class);
- final boolean wantEnabled = !String.valueOf(Settings.Secure.LOCATION_MODE_OFF).equals(mode);
- waitUntil("Location " + (wantEnabled ? "not enabled" : "still enabled"),
- () -> wantEnabled == locationManager.isLocationEnabled());
- }
-
- // Returns "true", "false" or "none"
- private String getWifiMeteredStatus(String ssid) {
- // Interestingly giving the SSID as an argument to list wifi-networks
- // only works iff the network in question has the "false" policy.
- // Also unfortunately runShellCommand does not pass the command to the interpreter
- // so it's not possible to | grep the ssid.
- final String command = "cmd netpolicy list wifi-networks";
- final String policyString = SystemUtil.runShellCommand(command);
-
- final Matcher m = Pattern.compile("^" + ssid + ";(true|false|none)$",
- Pattern.MULTILINE | Pattern.UNIX_LINES).matcher(policyString);
- if (!m.find()) {
- fail("Unexpected format from cmd netpolicy (when looking for " + ssid + "): "
- + policyString);
- }
- return m.group(1);
+ return mNetworkingHelper.hasEthernetConnection();
}
private void setWifiMeteredState(boolean metered) throws Exception {
- if (metered) {
- // Make sure unmetered cellular networks don't interfere.
- setAirplaneMode(true);
- setWifiState(true, mCm, mWifiManager);
- }
- final String ssid = getWifiSSID();
- setWifiMeteredState(ssid, metered ? "true" : "false");
- }
-
- // metered should be "true", "false" or "none"
- private void setWifiMeteredState(String ssid, String metered) throws Exception {
- if (metered.equals(getWifiMeteredStatus(ssid))) {
- return;
- }
- SystemUtil.runShellCommand("cmd netpolicy set metered-network " + ssid + " " + metered);
- assertEquals(getWifiMeteredStatus(ssid), metered);
+ mNetworkingHelper.setWifiMeteredState(metered);
}
/**
* Ensure WiFi is enabled, and block until we've verified that we are in fact connected.
*/
private void connectToWifi() throws Exception {
- setWifiState(true, mCm, mWifiManager);
+ mNetworkingHelper.setWifiState(true);
}
/**
* Ensure WiFi is disabled, and block until we've verified that we are in fact disconnected.
*/
private void disconnectFromWifi() throws Exception {
- setWifiState(false, mCm, mWifiManager);
- }
-
- /** Ensures that the device has a wifi network saved. */
- static void ensureSavedWifiNetwork(WifiManager wifiManager) {
- final List<WifiConfiguration> savedNetworks =
- ShellIdentityUtils.invokeMethodWithShellPermissions(
- wifiManager, WifiManager::getConfiguredNetworks);
- assertFalse("Need at least one saved wifi network", savedNetworks.isEmpty());
- }
-
- /**
- * Set Wifi connection to specific state, and block until we've verified
- * that we are in the state.
- * Taken from {@link android.net.http.cts.ApacheHttpClientTest}.
- */
- static void setWifiState(final boolean enable,
- final ConnectivityManager cm, final WifiManager wm) throws Exception {
- if (enable != isWiFiConnected(cm, wm)) {
- NetworkRequest nr = new NetworkRequest.Builder().clearCapabilities().build();
- NetworkCapabilities nc = new NetworkCapabilities.Builder()
- .addTransportType(TRANSPORT_WIFI)
- .build();
- NetworkTracker tracker = new NetworkTracker(nc, enable, cm);
- cm.registerNetworkCallback(nr, tracker);
-
- if (enable) {
- SystemUtil.runShellCommand("svc wifi enable");
- waitUntil("Failed to enable Wifi", 30 /* seconds */, () -> wm.isWifiEnabled());
- //noinspection deprecation
- SystemUtil.runWithShellPermissionIdentity(wm::reconnect,
- android.Manifest.permission.NETWORK_SETTINGS);
- } else {
- SystemUtil.runShellCommand("svc wifi disable");
- }
-
- tracker.waitForStateChange();
-
- assertTrue("Wifi must be " + (enable ? "connected to" : "disconnected from")
- + " an access point for this test.",
- enable == isWiFiConnected(cm, wm));
-
- cm.unregisterNetworkCallback(tracker);
- }
- }
-
- static boolean isWiFiConnected(final ConnectivityManager cm, final WifiManager wm) {
- if (!wm.isWifiEnabled()) {
- return false;
- }
- final Network network = cm.getActiveNetwork();
- if (network == null) {
- return false;
- }
- final NetworkCapabilities networkCapabilities = cm.getNetworkCapabilities(network);
- return networkCapabilities != null && networkCapabilities.hasTransport(TRANSPORT_WIFI);
+ mNetworkingHelper.setWifiState(false);
}
/**
@@ -1029,13 +835,14 @@ public class ConnectivityConstraintTest extends BaseJobSchedulerTest {
* @see #checkDeviceSupportsMobileData()
*/
private void disconnectWifiToConnectToMobile() throws Exception {
- setAirplaneMode(false);
+ mNetworkingHelper.setAllNetworksEnabled(true);
if (mHasWifi && mWifiManager.isWifiEnabled()) {
NetworkRequest nr = new NetworkRequest.Builder().clearCapabilities().build();
NetworkCapabilities nc = new NetworkCapabilities.Builder()
.addTransportType(TRANSPORT_CELLULAR)
.build();
- NetworkTracker tracker = new NetworkTracker(nc, true, mCm);
+ NetworkingHelper.NetworkTracker tracker =
+ new NetworkingHelper.NetworkTracker(nc, true, mCm);
mCm.registerNetworkCallback(nr, tracker);
disconnectFromWifi();
@@ -1052,107 +859,6 @@ public class ConnectivityConstraintTest extends BaseJobSchedulerTest {
* If the policy is on, it interferes with tests that relies on metered connection.
*/
private void setDataSaverEnabled(boolean enabled) throws Exception {
- SystemUtil.runShellCommand(getInstrumentation(),
- enabled ? RESTRICT_BACKGROUND_ON_CMD : RESTRICT_BACKGROUND_OFF_CMD);
- }
-
- private boolean isAirplaneModeOn() throws Exception {
- final String output = SystemUtil.runShellCommand(getInstrumentation(),
- "cmd connectivity airplane-mode").trim();
- return "enabled".equals(output);
- }
-
- private void setAirplaneMode(boolean on) throws Exception {
- if (isAirplaneModeOn() == on) {
- return;
- }
- final CallbackAsserter airplaneModeBroadcastAsserter = CallbackAsserter.forBroadcast(
- new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));
- SystemUtil.runShellCommand(getInstrumentation(),
- "cmd connectivity airplane-mode " + (on ? "enable" : "disable"));
- airplaneModeBroadcastAsserter.assertCalled("Didn't get airplane mode changed broadcast",
- 15 /* 15 seconds */);
- waitUntil("Networks didn't change to " + (!on ? " on" : " off"), 60 /* seconds */,
- () -> {
- if (on) {
- return mCm.getActiveNetwork() == null
- && (!mHasWifi || !isWiFiConnected(mCm, mWifiManager));
- } else {
- return mCm.getActiveNetwork() != null;
- }
- });
- // Wait some time for the network changes to propagate. Can't use
- // waitUntil(isAirplaneModeOn() == on) because the response quickly gives the new
- // airplane mode status even though the network changes haven't propagated all the way to
- // JobScheduler.
- Thread.sleep(5000);
- }
-
- private static class NetworkTracker extends ConnectivityManager.NetworkCallback {
- private static final int MSG_CHECK_ACTIVE_NETWORK = 1;
- private final ConnectivityManager mCm;
-
- private final CountDownLatch mReceiveLatch = new CountDownLatch(1);
-
- private final NetworkCapabilities mExpectedCapabilities;
-
- private final boolean mExpectedConnected;
-
- private final Handler mHandler = new Handler(Looper.getMainLooper()) {
- @Override
- public void handleMessage(Message msg) {
- if (msg.what == MSG_CHECK_ACTIVE_NETWORK) {
- checkActiveNetwork();
- }
- }
- };
-
- private NetworkTracker(NetworkCapabilities expectedCapabilities, boolean expectedConnected,
- ConnectivityManager cm) {
- mExpectedCapabilities = expectedCapabilities;
- mExpectedConnected = expectedConnected;
- mCm = cm;
- }
-
- @Override
- public void onAvailable(Network network) {
- // Available doesn't mean it's the active network. We need to check that separately.
- checkActiveNetwork();
- }
-
- @Override
- public void onLost(Network network) {
- checkActiveNetwork();
- }
-
- boolean waitForStateChange() throws InterruptedException {
- checkActiveNetwork();
- return mReceiveLatch.await(60, TimeUnit.SECONDS);
- }
-
- private void checkActiveNetwork() {
- mHandler.removeMessages(MSG_CHECK_ACTIVE_NETWORK);
- if (mReceiveLatch.getCount() == 0) {
- return;
- }
-
- Network activeNetwork = mCm.getActiveNetwork();
- if (mExpectedConnected) {
- if (activeNetwork != null && mExpectedCapabilities.satisfiedByNetworkCapabilities(
- mCm.getNetworkCapabilities(activeNetwork))) {
- mReceiveLatch.countDown();
- } else {
- mHandler.sendEmptyMessageDelayed(MSG_CHECK_ACTIVE_NETWORK, 5000);
- }
- } else {
- if (activeNetwork == null
- || !mExpectedCapabilities.satisfiedByNetworkCapabilities(
- mCm.getNetworkCapabilities(activeNetwork))) {
- mReceiveLatch.countDown();
- } else {
- mHandler.sendEmptyMessageDelayed(MSG_CHECK_ACTIVE_NETWORK, 5000);
- }
- }
- }
+ mNetworkingHelper.setDataSaverEnabled(enabled);
}
}
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
index b885a57ec25..3f386fac7c4 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
@@ -18,23 +18,17 @@ package android.jobscheduler.cts;
import static android.app.job.JobInfo.NETWORK_TYPE_ANY;
import static android.app.job.JobInfo.NETWORK_TYPE_NONE;
-import static android.jobscheduler.cts.ConnectivityConstraintTest.ensureSavedWifiNetwork;
-import static android.jobscheduler.cts.ConnectivityConstraintTest.isWiFiConnected;
-import static android.jobscheduler.cts.ConnectivityConstraintTest.setWifiState;
import static android.jobscheduler.cts.TestAppInterface.TEST_APP_PACKAGE;
import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED;
import static com.android.compatibility.common.util.TestUtils.waitUntil;
-import static junit.framework.Assert.fail;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
-import android.Manifest;
import android.app.AppOpsManager;
import android.app.job.JobInfo;
import android.app.job.JobParameters;
@@ -44,9 +38,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.jobscheduler.cts.jobtestapp.TestJobSchedulerReceiver;
-import android.location.LocationManager;
-import android.net.ConnectivityManager;
-import android.net.wifi.WifiManager;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.Temperature;
@@ -64,23 +55,14 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.compatibility.common.util.AppOpsUtils;
import com.android.compatibility.common.util.AppStandbyUtils;
import com.android.compatibility.common.util.BatteryUtils;
-import com.android.compatibility.common.util.CallbackAsserter;
import com.android.compatibility.common.util.DeviceConfigStateHelper;
-import com.android.compatibility.common.util.SystemUtil;
import com.android.compatibility.common.util.ThermalUtils;
-import junit.framework.AssertionFailedError;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.io.IOException;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
/**
* Tests related to job throttling -- device idle, app standby and battery saver.
*/
@@ -106,22 +88,15 @@ public class JobThrottlingTest {
private Context mContext;
private UiDevice mUiDevice;
+ private NetworkingHelper mNetworkingHelper;
private PowerManager mPowerManager;
private int mTestJobId;
private int mTestPackageUid;
private boolean mDeviceInDoze;
private boolean mDeviceIdleEnabled;
private boolean mAppStandbyEnabled;
- private WifiManager mWifiManager;
- private ConnectivityManager mCm;
- /** Whether the device running these tests supports WiFi. */
- private boolean mHasWifi;
- /** Track whether WiFi was enabled in case we turn it off. */
- private boolean mInitialWiFiState;
- private boolean mInitialAirplaneModeState;
private String mInitialDisplayTimeout;
private String mInitialRestrictedBucketEnabled;
- private String mInitialLocationMode;
private String mInitialBatteryStatsConstants;
private boolean mAutomotiveDevice;
private boolean mLeanbackOnly;
@@ -154,6 +129,8 @@ public class JobThrottlingTest {
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ mNetworkingHelper =
+ new NetworkingHelper(InstrumentationRegistry.getInstrumentation(), mContext);
mPowerManager = mContext.getSystemService(PowerManager.class);
mDeviceInDoze = mPowerManager.isDeviceIdleMode();
mTestPackageUid = mContext.getPackageManager().getPackageUid(TEST_APP_PACKAGE, 0);
@@ -171,11 +148,6 @@ public class JobThrottlingTest {
} else {
Log.w(TAG, "App standby not enabled on test device");
}
- mWifiManager = mContext.getSystemService(WifiManager.class);
- mCm = mContext.getSystemService(ConnectivityManager.class);
- mHasWifi = mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI);
- mInitialWiFiState = mWifiManager.isWifiEnabled();
- mInitialAirplaneModeState = isAirplaneModeOn();
mInitialRestrictedBucketEnabled = Settings.Global.getString(mContext.getContentResolver(),
Settings.Global.ENABLE_RESTRICTED_BUCKET);
mInitialBatteryStatsConstants = Settings.Global.getString(mContext.getContentResolver(),
@@ -183,8 +155,6 @@ public class JobThrottlingTest {
// Make sure ACTION_CHARGING is sent immediately.
Settings.Global.putString(mContext.getContentResolver(),
Settings.Global.BATTERY_STATS_CONSTANTS, "battery_charged_delay_ms=0");
- mInitialLocationMode = Settings.Secure.getString(mContext.getContentResolver(),
- Settings.Secure.LOCATION_MODE);
// Make sure test jobs can run regardless of bucket.
mDeviceConfigStateHelper =
new DeviceConfigStateHelper(DeviceConfig.NAMESPACE_JOB_SCHEDULER);
@@ -603,7 +573,7 @@ public class JobThrottlingTest {
mDeviceConfigStateHelper.set("qc_timing_session_coalescing_duration_ms", "0");
mDeviceConfigStateHelper.set("qc_max_session_count_restricted", "0");
- setAirplaneMode(true);
+ mNetworkingHelper.setAllNetworksEnabled(false);
setScreenState(true);
setChargingState(false);
@@ -634,9 +604,9 @@ public class JobThrottlingTest {
assumeTrue("app standby not enabled", mAppStandbyEnabled);
assumeFalse("not testable in automotive device", mAutomotiveDevice);
assumeFalse("not testable in leanback device", mLeanbackOnly);
-
- assumeTrue(mHasWifi);
- ensureSavedWifiNetwork(mWifiManager);
+ assumeFalse("not testable, since ethernet is connected", hasEthernetConnection());
+ assumeTrue(mNetworkingHelper.hasWifiFeature());
+ mNetworkingHelper.ensureSavedWifiNetwork();
setRestrictedBucketEnabled(true);
@@ -644,7 +614,7 @@ public class JobThrottlingTest {
mDeviceConfigStateHelper.set("qc_timing_session_coalescing_duration_ms", "0");
mDeviceConfigStateHelper.set("qc_max_session_count_restricted", "0");
- setAirplaneMode(true);
+ mNetworkingHelper.setAllNetworksEnabled(false);
setScreenState(true);
setChargingState(false);
@@ -673,9 +643,8 @@ public class JobThrottlingTest {
assertFalse("New job started in RESTRICTED bucket", mTestAppInterface.awaitJobStart(3_000));
// Add network
- setAirplaneMode(false);
- setWifiState(true, mCm, mWifiManager);
- setWifiMeteredState(false);
+ mNetworkingHelper.setAllNetworksEnabled(true);
+ mNetworkingHelper.setWifiMeteredState(false);
runJob();
assertTrue("New job didn't start in RESTRICTED bucket",
mTestAppInterface.awaitJobStart(5_000));
@@ -978,8 +947,8 @@ public class JobThrottlingTest {
assumeFalse("not testable in automotive device", mAutomotiveDevice);
assumeFalse("not testable in leanback device", mLeanbackOnly);
- assumeTrue(mHasWifi);
- ensureSavedWifiNetwork(mWifiManager);
+ assumeTrue(mNetworkingHelper.hasWifiFeature());
+ mNetworkingHelper.ensureSavedWifiNetwork();
setRestrictedBucketEnabled(true);
setTestPackageStandbyBucket(Bucket.RESTRICTED);
@@ -989,9 +958,8 @@ public class JobThrottlingTest {
mDeviceConfigStateHelper.set("qc_max_session_count_restricted", "0");
// Satisfy all additional constraints.
- setAirplaneMode(false);
- setWifiState(true, mCm, mWifiManager);
- setWifiMeteredState(false);
+ mNetworkingHelper.setAllNetworksEnabled(true);
+ mNetworkingHelper.setWifiMeteredState(false);
setChargingState(true);
BatteryUtils.runDumpsysBatterySetLevel(100);
setScreenState(false);
@@ -1004,13 +972,12 @@ public class JobThrottlingTest {
runJob();
assertTrue("New job didn't start in RESTRICTED bucket",
mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
- setAirplaneMode(true);
+ mNetworkingHelper.setAllNetworksEnabled(false);
assertTrue("New job didn't stop when connectivity dropped",
mTestAppInterface.awaitJobStop(DEFAULT_WAIT_TIMEOUT));
assertEquals(JobParameters.STOP_REASON_CONSTRAINT_CONNECTIVITY,
mTestAppInterface.getLastParams().getStopReason());
- setAirplaneMode(false);
- setWifiState(true, mCm, mWifiManager);
+ mNetworkingHelper.setAllNetworksEnabled(true);
// Idle
mTestAppInterface.scheduleJob(false, NETWORK_TYPE_ANY, false);
@@ -1195,23 +1162,12 @@ public class JobThrottlingTest {
Settings.Global.BATTERY_STATS_CONSTANTS, mInitialBatteryStatsConstants);
removeTestAppFromTempWhitelist();
- // Ensure that we leave WiFi in its previous state.
- if (mHasWifi && mWifiManager.isWifiEnabled() != mInitialWiFiState) {
- try {
- setWifiState(mInitialWiFiState, mCm, mWifiManager);
- } catch (AssertionFailedError e) {
- // Don't fail the test just because wifi state wasn't set in tearDown.
- Log.e(TAG, "Failed to return wifi state to " + mInitialWiFiState, e);
- }
- }
+ mNetworkingHelper.tearDown();
mDeviceConfigStateHelper.restoreOriginalValues();
mActivityManagerDeviceConfigStateHelper.restoreOriginalValues();
Settings.Global.putString(mContext.getContentResolver(),
Settings.Global.ENABLE_RESTRICTED_BUCKET, mInitialRestrictedBucketEnabled);
- if (isAirplaneModeOn() != mInitialAirplaneModeState) {
- setAirplaneMode(mInitialAirplaneModeState);
- }
- setLocationMode(mInitialLocationMode);
+
mUiDevice.executeShellCommand(
"cmd jobscheduler reset-execution-quota -u " + UserHandle.myUserId()
+ " " + TEST_APP_PACKAGE);
@@ -1367,110 +1323,8 @@ public class JobThrottlingTest {
+ " -u " + UserHandle.myUserId() + " " + TEST_APP_PACKAGE + " " + mTestJobId);
}
- private boolean isAirplaneModeOn() throws IOException {
- final String output =
- mUiDevice.executeShellCommand("cmd connectivity airplane-mode").trim();
- return "enabled".equals(output);
- }
-
- private void setAirplaneMode(boolean on) throws Exception {
- final CallbackAsserter airplaneModeBroadcastAsserter = CallbackAsserter.forBroadcast(
- new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));
- mUiDevice.executeShellCommand(
- "cmd connectivity airplane-mode " + (on ? "enable" : "disable"));
- airplaneModeBroadcastAsserter.assertCalled("Didn't get airplane mode changed broadcast",
- 15 /* 15 seconds */);
- if (!on && mHasWifi) {
- // Force wifi to connect ASAP.
- mUiDevice.executeShellCommand("svc wifi enable");
- waitUntil("Failed to enable Wifi", 30 /* seconds */,
- () -> {
- return mWifiManager.isWifiEnabled();
- });
- //noinspection deprecation
- SystemUtil.runWithShellPermissionIdentity(mWifiManager::reconnect,
- android.Manifest.permission.NETWORK_SETTINGS);
- }
- waitUntil("Networks didn't change to " + (!on ? "on" : "off"), 60 /* seconds */,
- () -> {
- if (on) {
- return mCm.getActiveNetwork() == null
- && (!mHasWifi || !isWiFiConnected(mCm, mWifiManager));
- } else {
- return mCm.getActiveNetwork() != null;
- }
- });
- // Wait some time for the network changes to propagate. Can't use
- // waitUntil(isAirplaneModeOn() == on) because the response quickly gives the new
- // airplane mode status even though the network changes haven't propagated all the way to
- // JobScheduler.
- Thread.sleep(5000);
- }
-
- private static String unquoteSSID(String ssid) {
- // SSID is returned surrounded by quotes if it can be decoded as UTF-8.
- // Otherwise it's guaranteed not to start with a quote.
- if (ssid.charAt(0) == '"') {
- return ssid.substring(1, ssid.length() - 1);
- } else {
- return ssid;
- }
- }
-
- private String getWifiSSID() throws Exception {
- // Location needs to be enabled to get the WiFi information.
- setLocationMode(String.valueOf(Settings.Secure.LOCATION_MODE_ON));
- final AtomicReference<String> ssid = new AtomicReference<>();
- SystemUtil.runWithShellPermissionIdentity(() -> {
- ssid.set(mWifiManager.getConnectionInfo().getSSID());
- }, Manifest.permission.ACCESS_FINE_LOCATION);
- return unquoteSSID(ssid.get());
- }
-
- private void setLocationMode(String mode) throws Exception {
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.LOCATION_MODE, mode);
- final LocationManager locationManager = mContext.getSystemService(LocationManager.class);
- final boolean wantEnabled = !String.valueOf(Settings.Secure.LOCATION_MODE_OFF).equals(mode);
- waitUntil("Location " + (wantEnabled ? "not enabled" : "still enabled"),
- () -> wantEnabled == locationManager.isLocationEnabled());
- }
-
- // Returns "true", "false" or "none"
- private String getWifiMeteredStatus(String ssid) {
- // Interestingly giving the SSID as an argument to list wifi-networks
- // only works iff the network in question has the "false" policy.
- // Also unfortunately runShellCommand does not pass the command to the interpreter
- // so it's not possible to | grep the ssid.
- final String command = "cmd netpolicy list wifi-networks";
- final String policyString = SystemUtil.runShellCommand(command);
-
- final Matcher m = Pattern.compile("^" + ssid + ";(true|false|none)$",
- Pattern.MULTILINE | Pattern.UNIX_LINES).matcher(policyString);
- if (!m.find()) {
- fail("Unexpected format from cmd netpolicy (when looking for " + ssid + "): "
- + policyString);
- }
- return m.group(1);
- }
-
- private void setWifiMeteredState(boolean metered) throws Exception {
- if (metered) {
- // Make sure unmetered cellular networks don't interfere.
- setAirplaneMode(true);
- setWifiState(true, mCm, mWifiManager);
- }
- final String ssid = getWifiSSID();
- setWifiMeteredState(ssid, metered ? "true" : "false");
- }
-
- // metered should be "true", "false" or "none"
- private void setWifiMeteredState(String ssid, String metered) {
- if (metered.equals(getWifiMeteredStatus(ssid))) {
- return;
- }
- SystemUtil.runShellCommand("cmd netpolicy set metered-network " + ssid + " " + metered);
- assertEquals(getWifiMeteredStatus(ssid), metered);
+ private boolean hasEthernetConnection() {
+ return mNetworkingHelper.hasEthernetConnection();
}
private String getJobState() throws Exception {
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/NetworkingHelper.java b/tests/JobScheduler/src/android/jobscheduler/cts/NetworkingHelper.java
new file mode 100644
index 00000000000..1402975cfe6
--- /dev/null
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/NetworkingHelper.java
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.jobscheduler.cts;
+
+import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+
+import static com.android.compatibility.common.util.TestUtils.waitUntil;
+
+import static junit.framework.Assert.fail;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import android.Manifest;
+import android.annotation.NonNull;
+import android.app.Instrumentation;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.location.LocationManager;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.provider.Settings;
+import android.util.Log;
+
+import com.android.compatibility.common.util.CallbackAsserter;
+import com.android.compatibility.common.util.ShellIdentityUtils;
+import com.android.compatibility.common.util.SystemUtil;
+
+import junit.framework.AssertionFailedError;
+
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class NetworkingHelper {
+ private static final String TAG = "JsNetworkingUtils";
+
+ private static final String RESTRICT_BACKGROUND_GET_CMD =
+ "cmd netpolicy get restrict-background";
+ private static final String RESTRICT_BACKGROUND_ON_CMD =
+ "cmd netpolicy set restrict-background true";
+ private static final String RESTRICT_BACKGROUND_OFF_CMD =
+ "cmd netpolicy set restrict-background false";
+
+ private final Context mContext;
+ private final Instrumentation mInstrumentation;
+
+ private final ConnectivityManager mConnectivityManager;
+ private final WifiManager mWifiManager;
+
+ /** Whether the device running these tests supports WiFi. */
+ private final boolean mHasWifi;
+ /** Whether the device running these tests supports ethernet. */
+ private final boolean mHasEthernet;
+ /** Whether the device running these tests supports telephony. */
+ private final boolean mHasTelephony;
+
+ private final boolean mInitialAirplaneModeState;
+ private final boolean mInitialDataSaverState;
+ private final String mInitialLocationMode;
+ private final boolean mInitialWiFiState;
+ private String mInitialWiFiMeteredState;
+ private String mInitialWiFiSSID;
+
+ NetworkingHelper(@NonNull Instrumentation instrumentation, @NonNull Context context)
+ throws Exception {
+ mContext = context;
+ mInstrumentation = instrumentation;
+
+ mConnectivityManager = context.getSystemService(ConnectivityManager.class);
+ mWifiManager = context.getSystemService(WifiManager.class);
+
+ PackageManager packageManager = mContext.getPackageManager();
+ mHasWifi = packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI);
+ mHasEthernet = packageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET);
+ mHasTelephony = packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
+
+ mInitialAirplaneModeState = isAirplaneModeOn();
+ mInitialDataSaverState = isDataSaverEnabled();
+ mInitialLocationMode = Settings.Secure.getString(
+ mContext.getContentResolver(), Settings.Secure.LOCATION_MODE);
+ mInitialWiFiState = mHasWifi && isWifiEnabled();
+ }
+
+ /** Ensures that the device has a wifi network saved. */
+ void ensureSavedWifiNetwork() throws Exception {
+ if (!mHasWifi) {
+ return;
+ }
+ final List<WifiConfiguration> savedNetworks =
+ ShellIdentityUtils.invokeMethodWithShellPermissions(
+ mWifiManager, WifiManager::getConfiguredNetworks);
+ assertFalse("Need at least one saved wifi network", savedNetworks.isEmpty());
+
+ setWifiState(true);
+ if (mInitialWiFiSSID == null) {
+ mInitialWiFiSSID = getWifiSSID();
+ mInitialWiFiMeteredState = getWifiMeteredStatus(mInitialWiFiSSID);
+ }
+ }
+
+ // Returns "true", "false", or "none".
+ private String getWifiMeteredStatus(String ssid) {
+ // Interestingly giving the SSID as an argument to list wifi-networks
+ // only works iff the network in question has the "false" policy.
+ // Also unfortunately runShellCommand does not pass the command to the interpreter
+ // so it's not possible to | grep the ssid.
+ final String command = "cmd netpolicy list wifi-networks";
+ final String policyString = SystemUtil.runShellCommand(command);
+
+ final Matcher m = Pattern.compile(ssid + ";(true|false|none)",
+ Pattern.MULTILINE | Pattern.UNIX_LINES).matcher(policyString);
+ if (!m.find()) {
+ fail("Unexpected format from cmd netpolicy (when looking for " + ssid + "): "
+ + policyString);
+ }
+ return m.group(1);
+ }
+
+ @NonNull
+ private String getWifiSSID() throws Exception {
+ // Location needs to be enabled to get the WiFi information.
+ setLocationMode(String.valueOf(Settings.Secure.LOCATION_MODE_ON));
+ final AtomicReference<String> ssid = new AtomicReference<>();
+ SystemUtil.runWithShellPermissionIdentity(
+ () -> ssid.set(mWifiManager.getConnectionInfo().getSSID()),
+ Manifest.permission.ACCESS_FINE_LOCATION);
+ return unquoteSSID(ssid.get());
+ }
+
+ boolean hasEthernetConnection() {
+ if (!mHasEthernet) return false;
+ Network[] networks = mConnectivityManager.getAllNetworks();
+ for (Network network : networks) {
+ if (mConnectivityManager.getNetworkCapabilities(network)
+ .hasTransport(TRANSPORT_ETHERNET)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ boolean hasWifiFeature() {
+ return mHasWifi;
+ }
+
+ boolean isAirplaneModeOn() throws Exception {
+ final String output = SystemUtil.runShellCommand(mInstrumentation,
+ "cmd connectivity airplane-mode").trim();
+ return "enabled".equals(output);
+ }
+
+ boolean isDataSaverEnabled() throws Exception {
+ return SystemUtil
+ .runShellCommand(mInstrumentation, RESTRICT_BACKGROUND_GET_CMD)
+ .contains("enabled");
+ }
+
+ boolean isWiFiConnected() {
+ if (!mWifiManager.isWifiEnabled()) {
+ return false;
+ }
+ final Network network = mConnectivityManager.getActiveNetwork();
+ if (network == null) {
+ return false;
+ }
+ final NetworkCapabilities networkCapabilities =
+ mConnectivityManager.getNetworkCapabilities(network);
+ return networkCapabilities != null && networkCapabilities.hasTransport(TRANSPORT_WIFI);
+ }
+
+ boolean isWifiEnabled() {
+ return mWifiManager.isWifiEnabled();
+ }
+
+ /**
+ * Tries to set all network statuses to {@code enabled}.
+ * However, this does not support ethernet connections.
+ * Confirm that {@link #hasEthernetConnection()} returns false before relying on this.
+ */
+ void setAllNetworksEnabled(boolean enabled) throws Exception {
+ if (mHasWifi) {
+ setWifiState(enabled);
+ }
+ setAirplaneMode(!enabled);
+ }
+
+ void setAirplaneMode(boolean on) throws Exception {
+ if (isAirplaneModeOn() == on) {
+ return;
+ }
+ final CallbackAsserter airplaneModeBroadcastAsserter = CallbackAsserter.forBroadcast(
+ new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));
+ SystemUtil.runShellCommand(mInstrumentation,
+ "cmd connectivity airplane-mode " + (on ? "enable" : "disable"));
+ airplaneModeBroadcastAsserter.assertCalled("Didn't get airplane mode changed broadcast",
+ 15 /* 15 seconds */);
+ if (!on && mHasWifi) {
+ // Try to trigger some network connection.
+ setWifiState(true);
+ }
+ waitUntil("Airplane mode didn't change to " + (on ? " on" : " off"), 60 /* seconds */,
+ () -> {
+ // Airplane mode only affects the cellular network. If the device doesn't
+ // support cellular, then we can only check that the airplane mode toggle is on.
+ if (!mHasTelephony) {
+ return on == isAirplaneModeOn();
+ }
+ if (on) {
+ Network[] networks = mConnectivityManager.getAllNetworks();
+ for (Network network : networks) {
+ if (mConnectivityManager.getNetworkCapabilities(network)
+ .hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ return mConnectivityManager.getActiveNetwork() != null;
+ }
+ });
+ // Wait some time for the network changes to propagate. Can't use
+ // waitUntil(isAirplaneModeOn() == on) because the response quickly gives the new
+ // airplane mode status even though the network changes haven't propagated all the way to
+ // JobScheduler.
+ Thread.sleep(5000);
+ }
+
+ /**
+ * Ensures that restrict background data usage policy is turned off.
+ * If the policy is on, it interferes with tests that relies on metered connection.
+ */
+ void setDataSaverEnabled(boolean enabled) throws Exception {
+ SystemUtil.runShellCommand(mInstrumentation,
+ enabled ? RESTRICT_BACKGROUND_ON_CMD : RESTRICT_BACKGROUND_OFF_CMD);
+ }
+
+ private void setLocationMode(String mode) throws Exception {
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.LOCATION_MODE, mode);
+ final LocationManager locationManager = mContext.getSystemService(LocationManager.class);
+ final boolean wantEnabled = !String.valueOf(Settings.Secure.LOCATION_MODE_OFF).equals(mode);
+ waitUntil("Location " + (wantEnabled ? "not enabled" : "still enabled"),
+ () -> wantEnabled == locationManager.isLocationEnabled());
+ }
+
+ void setWifiMeteredState(boolean metered) throws Exception {
+ if (metered) {
+ // Make sure unmetered cellular networks don't interfere.
+ setAirplaneMode(true);
+ setWifiState(true);
+ }
+ final String ssid = getWifiSSID();
+ setWifiMeteredState(ssid, metered ? "true" : "false");
+ }
+
+ // metered should be "true", "false" or "none"
+ private void setWifiMeteredState(String ssid, String metered) {
+ if (metered.equals(getWifiMeteredStatus(ssid))) {
+ return;
+ }
+ SystemUtil.runShellCommand("cmd netpolicy set metered-network " + ssid + " " + metered);
+ assertEquals(getWifiMeteredStatus(ssid), metered);
+ }
+
+ /**
+ * Set Wifi connection to specific state, and block until we've verified
+ * that we are in the state.
+ * Taken from {@link android.net.http.cts.ApacheHttpClientTest}.
+ */
+ void setWifiState(final boolean enable) throws Exception {
+ if (enable != isWiFiConnected()) {
+ NetworkRequest nr = new NetworkRequest.Builder().clearCapabilities().build();
+ NetworkCapabilities nc = new NetworkCapabilities.Builder()
+ .addTransportType(TRANSPORT_WIFI)
+ .build();
+ NetworkTracker tracker = new NetworkTracker(nc, enable, mConnectivityManager);
+ mConnectivityManager.registerNetworkCallback(nr, tracker);
+
+ if (enable) {
+ SystemUtil.runShellCommand("svc wifi enable");
+ waitUntil("Failed to enable Wifi", 30 /* seconds */,
+ this::isWifiEnabled);
+ //noinspection deprecation
+ SystemUtil.runWithShellPermissionIdentity(mWifiManager::reconnect,
+ android.Manifest.permission.NETWORK_SETTINGS);
+ } else {
+ SystemUtil.runShellCommand("svc wifi disable");
+ }
+
+ tracker.waitForStateChange();
+
+ assertEquals("Wifi must be " + (enable ? "connected to" : "disconnected from")
+ + " an access point for this test.", enable, isWiFiConnected());
+
+ mConnectivityManager.unregisterNetworkCallback(tracker);
+ }
+ }
+
+ void tearDown() throws Exception {
+ // Restore initial restrict background data usage policy
+ setDataSaverEnabled(mInitialDataSaverState);
+
+ // Ensure that we leave WiFi in its previous state.
+ if (mHasWifi) {
+ if (mInitialWiFiSSID != null) {
+ setWifiMeteredState(mInitialWiFiSSID, mInitialWiFiMeteredState);
+ }
+ if (mWifiManager.isWifiEnabled() != mInitialWiFiState) {
+ try {
+ setWifiState(mInitialWiFiState);
+ } catch (AssertionFailedError e) {
+ // Don't fail the test just because wifi state wasn't set in tearDown.
+ Log.e(TAG, "Failed to return wifi state to " + mInitialWiFiState, e);
+ }
+ }
+ }
+
+ // Restore initial airplane mode status. Do it after setting wifi in case wifi was
+ // originally metered.
+ if (isAirplaneModeOn() != mInitialAirplaneModeState) {
+ setAirplaneMode(mInitialAirplaneModeState);
+ }
+
+ setLocationMode(mInitialLocationMode);
+ }
+
+ private String unquoteSSID(String ssid) {
+ // SSID is returned surrounded by quotes if it can be decoded as UTF-8.
+ // Otherwise it's guaranteed not to start with a quote.
+ if (ssid.charAt(0) == '"') {
+ return ssid.substring(1, ssid.length() - 1);
+ } else {
+ return ssid;
+ }
+ }
+
+ static class NetworkTracker extends ConnectivityManager.NetworkCallback {
+ private static final int MSG_CHECK_ACTIVE_NETWORK = 1;
+ private final ConnectivityManager mConnectivityManager;
+
+ private final CountDownLatch mReceiveLatch = new CountDownLatch(1);
+
+ private final NetworkCapabilities mExpectedCapabilities;
+
+ private final boolean mExpectedConnected;
+
+ private final Handler mHandler = new Handler(Looper.getMainLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == MSG_CHECK_ACTIVE_NETWORK) {
+ checkActiveNetwork();
+ }
+ }
+ };
+
+ NetworkTracker(NetworkCapabilities expectedCapabilities, boolean expectedConnected,
+ ConnectivityManager cm) {
+ mExpectedCapabilities = expectedCapabilities;
+ mExpectedConnected = expectedConnected;
+ mConnectivityManager = cm;
+ }
+
+ @Override
+ public void onAvailable(Network network) {
+ // Available doesn't mean it's the active network. We need to check that separately.
+ checkActiveNetwork();
+ }
+
+ @Override
+ public void onLost(Network network) {
+ checkActiveNetwork();
+ }
+
+ boolean waitForStateChange() throws InterruptedException {
+ checkActiveNetwork();
+ return mReceiveLatch.await(60, TimeUnit.SECONDS);
+ }
+
+ private void checkActiveNetwork() {
+ mHandler.removeMessages(MSG_CHECK_ACTIVE_NETWORK);
+ if (mReceiveLatch.getCount() == 0) {
+ return;
+ }
+
+ Network activeNetwork = mConnectivityManager.getActiveNetwork();
+ if (mExpectedConnected) {
+ if (activeNetwork != null && mExpectedCapabilities.satisfiedByNetworkCapabilities(
+ mConnectivityManager.getNetworkCapabilities(activeNetwork))) {
+ mReceiveLatch.countDown();
+ } else {
+ mHandler.sendEmptyMessageDelayed(MSG_CHECK_ACTIVE_NETWORK, 5000);
+ }
+ } else {
+ if (activeNetwork == null
+ || !mExpectedCapabilities.satisfiedByNetworkCapabilities(
+ mConnectivityManager.getNetworkCapabilities(activeNetwork))) {
+ mReceiveLatch.countDown();
+ } else {
+ mHandler.sendEmptyMessageDelayed(MSG_CHECK_ACTIVE_NETWORK, 5000);
+ }
+ }
+ }
+ }
+}
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/VisualVoicemailServiceTest.java b/tests/tests/telephony/current/src/android/telephony/cts/VisualVoicemailServiceTest.java
index f77b879effe..f9691828646 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/VisualVoicemailServiceTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/VisualVoicemailServiceTest.java
@@ -532,7 +532,8 @@ public class VisualVoicemailServiceTest {
for (SmsMessage message : messages) {
String body = message.getMessageBody();
- if ((body == null || message.getReceivedEncodingType() == ENCODING_8BIT)
+ if ((body == null || (message.is3gpp()
+ && message.getReceivedEncodingType() == ENCODING_8BIT))
&& message.getUserData() != null) {
Log.d(TAG, "onReceive decode using UTF-8");
// Attempt to interpret the user data as UTF-8. UTF-8 string over data SMS using