From a0f49f2384fcbf1dff3b01d8511bd88effb600b6 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Thu, 18 Feb 2016 10:43:54 -0800 Subject: [PATCH] Refactored how data is shared between test apps. When running the device-site tests, it's necessary to share state between a second app and the main test app. Currently that's achieved through a shared preference file that is accessed by both apps (since they use a shared id), but this approach will not work on power save mode tests (because the test app will be in foreground and the background restrictions won't be applied in the second app). This change refactors the data sharing mechanism by: - Using an ordered broadcast that is sent from the test app to the secondary app. - Checking for the network status in the secondary app. - Moving the test logic to the client-side tests. BUG: 27127112 Change-Id: I44987701b908b329fdf40e3a7a97e9f30cfadecb --- tests/cts/hostside/app/AndroidManifest.xml | 7 +- .../net/hostside/ConnectivityManagerTest.java | 282 ++++++++++++------ tests/cts/hostside/app2/AndroidManifest.xml | 20 +- .../android/cts/net/hostside/app2/Common.java | 12 + .../hostside/app2/MyBroadcastReceiver.java | 126 +++++++- ...ostsideRestrictBackgroundNetworkTests.java | 133 +-------- 6 files changed, 362 insertions(+), 218 deletions(-) diff --git a/tests/cts/hostside/app/AndroidManifest.xml b/tests/cts/hostside/app/AndroidManifest.xml index f44fdd1dfc..c7978f8775 100644 --- a/tests/cts/hostside/app/AndroidManifest.xml +++ b/tests/cts/hostside/app/AndroidManifest.xml @@ -15,11 +15,12 @@ --> + package="com.android.cts.net.hostside"> - + + + diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java index 8975dabd3a..9a4f318ce8 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java @@ -16,24 +16,26 @@ package com.android.cts.net.hostside; +import static android.cts.util.SystemUtil.runShellCommand; import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.test.InstrumentationTestCase; -import android.util.Log; - -import java.net.HttpURLConnection; -import java.net.URL; +import java.io.IOException; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import android.app.Instrumentation; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.net.wifi.WifiManager; +import android.test.InstrumentationTestCase; +import android.util.Log; + /** * Tests for the {@link ConnectivityManager} API. * @@ -44,54 +46,91 @@ import java.util.concurrent.TimeUnit; public class ConnectivityManagerTest extends InstrumentationTestCase { private static final String TAG = "ConnectivityManagerTest"; + private static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2"; + + private static final int SLEEP_TIME_SEC = 1; + private static final boolean DEBUG = true; + + // Constants below must match values defined on app2's Common.java private static final String MANIFEST_RECEIVER = "ManifestReceiver"; private static final String DYNAMIC_RECEIVER = "DynamicReceiver"; - + private static final String ACTION_GET_COUNTERS = + "com.android.cts.net.hostside.app2.action.GET_COUNTERS"; + private static final String ACTION_CHECK_NETWORK = + "com.android.cts.net.hostside.app2.action.CHECK_NETWORK"; + private static final String EXTRA_ACTION = "com.android.cts.net.hostside.app2.extra.ACTION"; + private static final String EXTRA_RECEIVER_NAME = + "com.android.cts.net.hostside.app2.extra.RECEIVER_NAME"; + private static final String RESULT_SEPARATOR = ";"; private static final String STATUS_NETWORK_UNAVAILABLE_PREFIX = "NetworkUnavailable:"; private static final String STATUS_NETWORK_AVAILABLE_PREFIX = "NetworkAvailable:"; - private static final int NETWORK_TIMEOUT_MS = 15000; - private static final int SLEEP_TIME_SEC = 1; - + private Context mContext; + private Instrumentation mInstrumentation; private ConnectivityManager mCm; + private WifiManager mWfm; private int mUid; + private boolean mResetMeteredWifi = false; @Override public void setUp() throws Exception { super.setUp(); - final Context context = getInstrumentation().getContext(); - mCm = (ConnectivityManager) context.getSystemService(Activity.CONNECTIVITY_SERVICE); - mUid = context.getPackageManager() - .getPackageInfo(context.getPackageName(), 0).applicationInfo.uid; - final boolean metered = mCm.isActiveNetworkMetered(); - Log.i(TAG, getName() + ": uid=" + mUid + ", metered=" + metered); - assertTrue("Active network is not metered", metered); + mInstrumentation = getInstrumentation(); + mContext = mInstrumentation.getContext(); + mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); + mWfm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); + mUid = mContext.getPackageManager().getPackageInfo(TEST_APP2_PKG, 0).applicationInfo.uid; + final int myUid = mContext.getPackageManager() + .getPackageInfo(mContext.getPackageName(), 0).applicationInfo.uid; + + Log.d(TAG, "UIDS: test app=" + myUid + ", app2=" + mUid); + + setRestrictBackground(false); + setMeteredNetwork(); + + registerApp2BroadcastReceiver(); } + @Override + protected void tearDown() throws Exception { + super.tearDown(); + + if (mResetMeteredWifi) { + setWifiMeteredStatus(false); + } + } + public void testGetRestrictBackgroundStatus_disabled() throws Exception { + removeRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + assertRestrictBackgroundChangedReceived(0); + + // Sanity check: make sure status is always disabled, never whitelisted + addRestrictBackgroundWhitelist(mUid); + assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + assertRestrictBackgroundChangedReceived(0); } public void testGetRestrictBackgroundStatus_whitelisted() throws Exception { + setRestrictBackground(true); + assertRestrictBackgroundChangedReceived(1); + + addRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_WHITELISTED); + assertRestrictBackgroundChangedReceived(2); } public void testGetRestrictBackgroundStatus_enabled() throws Exception { + setRestrictBackground(true); + assertRestrictBackgroundChangedReceived(1); + + removeRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); + assertRestrictBackgroundChangedReceived(1); } - public void testRestrictBackgroundChangedNotReceived() throws Exception { - assertRestrictBackgroundChangedReceived(DYNAMIC_RECEIVER, 0); - assertRestrictBackgroundChangedReceived(MANIFEST_RECEIVER, 0); - } - - public void testRestrictBackgroundChangedReceivedOnce() throws Exception { - assertRestrictBackgroundChangedReceived(DYNAMIC_RECEIVER, 1); - assertRestrictBackgroundChangedReceived(MANIFEST_RECEIVER, 0); - } - - public void testRestrictBackgroundChangedReceivedTwice() throws Exception { - assertRestrictBackgroundChangedReceived(DYNAMIC_RECEIVER, 2); + public void assertRestrictBackgroundChangedReceived(int expectedCount) throws Exception { + assertRestrictBackgroundChangedReceived(DYNAMIC_RECEIVER, expectedCount); assertRestrictBackgroundChangedReceived(MANIFEST_RECEIVER, 0); } @@ -102,12 +141,12 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { final int maxAttempts = 5; do { attempts++; - count = getNumberBroadcastsReceived(getInstrumentation().getContext(), receiverName, - ACTION_RESTRICT_BACKGROUND_CHANGED); + count = getNumberBroadcastsReceived(receiverName, ACTION_RESTRICT_BACKGROUND_CHANGED); if (count == expectedCount) { break; } - Log.d(TAG, "Count is " + count + " after " + attempts + " attempts; sleeping " + Log.d(TAG, "Expecting count " + expectedCount + " but actual is " + count + " after " + + attempts + " attempts; sleeping " + SLEEP_TIME_SEC + " seconds before trying again"); Thread.sleep(SLEEP_TIME_SEC * 1000); } while (attempts <= maxAttempts); @@ -115,62 +154,139 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { + maxAttempts * SLEEP_TIME_SEC + " seconds", expectedCount, count); } + private String sendOrderedBroadcast(Intent intent) throws Exception { + final LinkedBlockingQueue result = new LinkedBlockingQueue<>(1); + Log.d(TAG, "Sending ordered broadcast: " + intent); + mContext.sendOrderedBroadcast(intent, null, new BroadcastReceiver() { - static int getNumberBroadcastsReceived(Context context, String receiverName, String action) - throws Exception { - final Context sharedContext = context.createPackageContext( - "com.android.cts.net.hostside.app2", Context.CONTEXT_IGNORE_SECURITY); - final SharedPreferences prefs = sharedContext.getSharedPreferences(receiverName, - Context.MODE_PRIVATE); - return prefs.getInt(action, 0); + @Override + public void onReceive(Context context, Intent intent) { + final String resultData = getResultData(); + if (resultData == null) { + Log.e(TAG, "Received null data from ordered intent"); + return; + } + result.offer(resultData); + } + }, null, 0, null, null); + + final String resultData = result.poll(60, TimeUnit.SECONDS); + assertNotNull("timeout waiting for ordered broadcast result", resultData); + Log.d(TAG, "Ordered broadcast response: " + resultData); + return resultData; } - private void assertRestrictBackgroundStatus(int expectedApiStatus) throws InterruptedException { - // First asserts the API returns the proper value... - final String expected = toString(expectedApiStatus); - Log.d(TAG, getName() + " (expecting " + expected + ")"); - final int apiStatus = mCm.getRestrictBackgroundStatus(); - String actualApiStatus = toString(apiStatus); - assertEquals("wrong status", expected, actualApiStatus); + private int getNumberBroadcastsReceived(String receiverName, String action) throws Exception { + final Intent intent = new Intent(ACTION_GET_COUNTERS); + intent.putExtra(EXTRA_ACTION, ACTION_RESTRICT_BACKGROUND_CHANGED); + intent.putExtra(EXTRA_RECEIVER_NAME, receiverName); + final String resultData = sendOrderedBroadcast(intent); + return Integer.valueOf(resultData); + } - //...then use a background thread to verify the actual network status. - final LinkedBlockingQueue result = new LinkedBlockingQueue<>(1); - new Thread(new Runnable() { - @Override - public void run() { - result.offer(checkNetworkStatus()); - } - }, "CheckNetworkThread").start(); - final String actualNetworkStatus = result.poll(10, TimeUnit.SECONDS); - assertNotNull("timeout waiting for background thread", actualNetworkStatus); - final String expectedPrefix = apiStatus == RESTRICT_BACKGROUND_STATUS_ENABLED ? - STATUS_NETWORK_UNAVAILABLE_PREFIX : STATUS_NETWORK_AVAILABLE_PREFIX; + private void assertRestrictBackgroundStatus(int expectedApiStatus) throws Exception { + final Intent intent = new Intent(ACTION_CHECK_NETWORK); + final String resultData = sendOrderedBroadcast(intent); + final String[] resultItems = resultData.split(RESULT_SEPARATOR); + final String actualApiStatus = toString(Integer.parseInt(resultItems[0])); + final String actualNetworkStatus = resultItems[1]; + + // First asserts the API returns the proper value... + assertEquals("wrong status", toString(expectedApiStatus), actualApiStatus); + + //...then the actual network status in the background thread. + final String expectedPrefix = expectedApiStatus == RESTRICT_BACKGROUND_STATUS_ENABLED ? + STATUS_NETWORK_UNAVAILABLE_PREFIX : STATUS_NETWORK_AVAILABLE_PREFIX; assertTrue("Wrong network status for API status " + actualApiStatus + ": " + actualNetworkStatus, actualNetworkStatus.startsWith(expectedPrefix)); } - protected String checkNetworkStatus() { - // TODO: connect to a hostside server instead - final String address = "http://example.com"; - final NetworkInfo networkInfo = mCm.getActiveNetworkInfo(); - Log.d(TAG, "Running checkNetworkStatus() on thread " + Thread.currentThread().getName() - + "\n\tactiveNetworkInfo: " + networkInfo + "\n\tURL: " + address); - String prefix = STATUS_NETWORK_AVAILABLE_PREFIX; - try { - final URL url = new URL(address); - final HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setReadTimeout(NETWORK_TIMEOUT_MS); - conn.setConnectTimeout(NETWORK_TIMEOUT_MS); - conn.setRequestMethod("GET"); - conn.setDoInput(true); - conn.connect(); - final int response = conn.getResponseCode(); - Log.d(TAG, "HTTP response for " + address + ": " + response); - } catch (Exception e) { - Log.d(TAG, "Exception getting " + address + ": " + e); - prefix = STATUS_NETWORK_UNAVAILABLE_PREFIX; + private String executeShellCommand(String command) throws IOException { + final String result = runShellCommand(mInstrumentation, command).trim(); + if (DEBUG) Log.d(TAG, "Command '" + command + "' returned '" + result + "'"); + return result; + } + + private void setMeteredNetwork() throws IOException { + final NetworkInfo info = mCm.getActiveNetworkInfo(); + final boolean metered = mCm.isActiveNetworkMetered(); + if (metered) { + Log.d(TAG, "Active network already metered: " + info); + return; } - return prefix + networkInfo; + final String netId = setWifiMeteredStatus(true); + assertTrue("Could not set wifi '" + netId + "' as metered (" + + mCm.getActiveNetworkInfo() +")", mCm.isActiveNetworkMetered()); + // Set flag so status is reverted on teardown. + mResetMeteredWifi = true; + } + + private String setWifiMeteredStatus(boolean metered) throws IOException { + mWfm.setWifiEnabled(true); + // TODO: if it's not guaranteed the device has wi-fi, we need to change the tests + // to make the actual verification of restrictions optional. + final String ssid = mWfm.getConnectionInfo().getSSID(); + assertNotNull("null SSID", ssid); + final String netId = ssid.trim().replaceAll("\"", ""); // remove quotes, if any. + assertFalse("empty SSID", ssid.isEmpty()); + + Log.i(TAG, "Setting wi-fi network " + netId + " metered status to " + metered); + final String setCommand = "cmd netpolicy set metered-network " + netId + " " + metered; + final String result = executeShellCommand(setCommand); + assertTrue("Command '" + setCommand + "' failed: " + result, result.isEmpty()); + + // Sanity check. + final String newStatus = executeShellCommand("cmd netpolicy get metered-network " + netId); + assertEquals("Metered status of wi-fi network " + netId + " not set properly", + newStatus.trim(), Boolean.toString(metered)); + return netId; + } + + private void setRestrictBackground(boolean enabled) throws IOException { + executeShellCommand("cmd netpolicy set restrict-background " + enabled); + final String output = executeShellCommand("cmd netpolicy get restrict-background "); + final String expectedSuffix = enabled ? "enabled" : "disabled"; + // TODO: use MoreAsserts? + assertTrue("output '" + output + "' should end with '" + expectedSuffix + "'", + output.endsWith(expectedSuffix)); + } + + private void addRestrictBackgroundWhitelist(int uid) throws Exception { + executeShellCommand("cmd netpolicy add restrict-background-whitelist " + uid); + assertRestrictBackgroundWhitelist(uid, true); + } + + private void removeRestrictBackgroundWhitelist(int uid) throws Exception { + executeShellCommand("cmd netpolicy remove restrict-background-whitelist " + uid); + assertRestrictBackgroundWhitelist(uid, false); + } + + private void assertRestrictBackgroundWhitelist(int uid, boolean expected) throws Exception { + final int maxTries = 5; + boolean actual = false; + for (int i = 1; i <= maxTries; i++) { + final String output = + executeShellCommand("cmd netpolicy list restrict-background-whitelist "); + actual = output.contains(Integer.toString(uid)); + if (expected == actual) { + return; + } + Log.v(TAG, "whitelist check for uid " + uid + " doesn't match yet (expected " + + expected + ", got " + actual + "); sleeping 1s before polling again"); + Thread.sleep(1000); + } + fail("whitelist check for uid " + uid + " failed: expected " + expected + ", got " + actual); + } + + /** + * Starts a service that will register a broadcast receiver to receive + * {@code RESTRICT_BACKGROUND_CHANGE} intents. + *

+ * The service must run in a separate app because otherwise it would be killed every time + * {@link #runDeviceTests(String, String)} is executed. + */ + private void registerApp2BroadcastReceiver() throws IOException { + executeShellCommand("am startservice com.android.cts.net.hostside.app2/.MyService"); } private String toString(int status) { diff --git a/tests/cts/hostside/app2/AndroidManifest.xml b/tests/cts/hostside/app2/AndroidManifest.xml index d69bf56a1c..fa4cb43d29 100644 --- a/tests/cts/hostside/app2/AndroidManifest.xml +++ b/tests/cts/hostside/app2/AndroidManifest.xml @@ -16,20 +16,28 @@ --> + package="com.android.cts.net.hostside.app2" > - - + + + diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java index 91caeda97d..3be4261258 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java @@ -18,6 +18,18 @@ package com.android.cts.net.hostside.app2; public final class Common { static final String TAG = "CtsNetApp2"; + + // Constants below must match values defined on app's ConnectivityManagerTest.java static final String MANIFEST_RECEIVER = "ManifestReceiver"; static final String DYNAMIC_RECEIVER = "DynamicReceiver"; + static final String ACTION_GET_COUNTERS = + "com.android.cts.net.hostside.app2.action.GET_COUNTERS"; + static final String ACTION_CHECK_NETWORK = + "com.android.cts.net.hostside.app2.action.CHECK_NETWORK"; + static final String EXTRA_ACTION = "com.android.cts.net.hostside.app2.extra.ACTION"; + static final String EXTRA_RECEIVER_NAME = + "com.android.cts.net.hostside.app2.extra.RECEIVER_NAME"; + static final char RESULT_SEPARATOR = ';'; + static final String STATUS_NETWORK_UNAVAILABLE_PREFIX = "NetworkUnavailable:"; + static final String STATUS_NETWORK_AVAILABLE_PREFIX = "NetworkAvailable:"; } diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java index 0cbf360d8f..65c7b6009d 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java @@ -13,21 +13,44 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.android.cts.net.hostside.app2; +import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; +import static com.android.cts.net.hostside.app2.Common.ACTION_CHECK_NETWORK; +import static com.android.cts.net.hostside.app2.Common.ACTION_GET_COUNTERS; +import static com.android.cts.net.hostside.app2.Common.EXTRA_ACTION; +import static com.android.cts.net.hostside.app2.Common.EXTRA_RECEIVER_NAME; import static com.android.cts.net.hostside.app2.Common.MANIFEST_RECEIVER; +import static com.android.cts.net.hostside.app2.Common.RESULT_SEPARATOR; +import static com.android.cts.net.hostside.app2.Common.STATUS_NETWORK_AVAILABLE_PREFIX; +import static com.android.cts.net.hostside.app2.Common.STATUS_NETWORK_UNAVAILABLE_PREFIX; import static com.android.cts.net.hostside.app2.Common.TAG; + +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; import android.util.Log; /** - * Receiver that stores received broadcasts in a shared preference. + * Receiver used to: + *

    + *
  1. Stored received RESTRICT_BACKGROUND_CHANGED broadcasts in a shared preference. + *
  2. Returned the number of RESTRICT_BACKGROUND_CHANGED broadcasts in an ordered broadcast. + *
*/ public class MyBroadcastReceiver extends BroadcastReceiver { + private static final int NETWORK_TIMEOUT_MS = 15 * 1000; + private final String mName; public MyBroadcastReceiver() { @@ -37,15 +60,106 @@ public class MyBroadcastReceiver extends BroadcastReceiver { MyBroadcastReceiver(String name) { Log.d(TAG, "Constructing MyBroadcastReceiver named " + name); mName = name; - } + } @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "onReceive() for " + mName + ": " + intent); + final String action = intent.getAction(); + switch (action) { + case ACTION_RESTRICT_BACKGROUND_CHANGED: + increaseCounter(context, action); + break; + case ACTION_GET_COUNTERS: + setResultDataFromCounter(context, intent); + break; + case ACTION_CHECK_NETWORK: + checkNetwork(context, intent); + break; + default: + Log.e(TAG, "received unexpected action: " + action); + } + } + + private void increaseCounter(Context context, String action) { final SharedPreferences prefs = context.getSharedPreferences(mName, Context.MODE_PRIVATE); - final String pref = intent.getAction(); - final int value = prefs.getInt(pref, 0) + 1; - Log.d(TAG, "Setting " + pref + " = " + value); - prefs.edit().putInt(pref, value).apply(); + final int value = prefs.getInt(action, 0) + 1; + Log.d(TAG, "increaseCounter('" + action + "'): setting '" + mName + "' to " + value); + prefs.edit().putInt(action, value).apply(); + } + + private int getCounter(Context context, String action, String receiverName) { + final SharedPreferences prefs = context.getSharedPreferences(receiverName, + Context.MODE_PRIVATE); + final int value = prefs.getInt(action, 0); + Log.d(TAG, "getCounter('" + action + "', '" + receiverName + "'): " + value); + return value; + } + + private void checkNetwork(final Context context, Intent intent) { + final ConnectivityManager cm = (ConnectivityManager) context + .getSystemService(Context.CONNECTIVITY_SERVICE); + + final StringBuilder data = new StringBuilder(); + final int apiStatus = cm.getRestrictBackgroundStatus(); + String netStatus; + try { + netStatus = checkNetworkStatus(cm); + } catch (InterruptedException e) { + Log.e(TAG, "Timeout checking network status"); + setResultData(null); + return; + } + data.append(apiStatus).append(RESULT_SEPARATOR).append(netStatus); + Log.d(TAG, "checkNetwork: returning " + data); + setResultData(data.toString()); + } + + private String checkNetworkStatus(final ConnectivityManager cm) throws InterruptedException { + final LinkedBlockingQueue result = new LinkedBlockingQueue<>(1); + new Thread(new Runnable() { + + @Override + public void run() { + // TODO: connect to a hostside server instead + final String address = "http://example.com"; + final NetworkInfo networkInfo = cm.getActiveNetworkInfo(); + Log.d(TAG, "Running checkNetworkStatus() on thread " + + Thread.currentThread().getName() + + "\n\tactiveNetworkInfo: " + networkInfo + "\n\tURL: " + address); + String prefix = STATUS_NETWORK_AVAILABLE_PREFIX; + try { + final URL url = new URL(address); + final HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setReadTimeout(NETWORK_TIMEOUT_MS); + conn.setConnectTimeout(NETWORK_TIMEOUT_MS); + conn.setRequestMethod("GET"); + conn.setDoInput(true); + conn.connect(); + final int response = conn.getResponseCode(); + Log.d(TAG, "HTTP response for " + address + ": " + response); + } catch (Exception e) { + Log.d(TAG, "Exception getting " + address + ": " + e); + prefix = STATUS_NETWORK_UNAVAILABLE_PREFIX + "Exception " + e + ":"; + } + result.offer(prefix + networkInfo); + } + }, mName).start(); + return result.poll(NETWORK_TIMEOUT_MS * 2, TimeUnit.MILLISECONDS); + } + + private void setResultDataFromCounter(Context context, Intent intent) { + final String action = intent.getStringExtra(EXTRA_ACTION); + if (action == null) { + Log.e(TAG, "Missing extra '" + EXTRA_ACTION + "' on " + intent); + return; + } + final String receiverName = intent.getStringExtra(EXTRA_RECEIVER_NAME); + if (receiverName == null) { + Log.e(TAG, "Missing extra '" + EXTRA_RECEIVER_NAME + "' on " + intent); + return; + } + final int counter = getCounter(context, action, receiverName); + setResultData(String.valueOf(counter)); } } diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java index 18047406cc..f2c3b1f7d2 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -17,30 +17,19 @@ package com.android.cts.net; import com.android.ddmlib.Log; -import com.android.tradefed.device.DeviceNotAvailableException; -import com.android.tradefed.device.WifiHelper; public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestCase { + private static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2"; private static final String TEST_APP2_APK = "CtsHostsideNetworkTestsApp2.apk"; - private int mUid; - private WifiHelper mWifiHelper; - @Override protected void setUp() throws Exception { super.setUp(); - mUid = getUid(TEST_PKG); - mWifiHelper = new WifiHelper(getDevice()); - - setWifiMeteredStatus(true); - setRestrictBackground(false); - uninstallPackage(TEST_APP2_PKG, false); installPackage(TEST_APP2_APK); - startBroadcastReceiverService(); } @Override @@ -48,103 +37,35 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC super.tearDown(); uninstallPackage(TEST_APP2_PKG, true); - setRestrictBackground(false); - setWifiMeteredStatus(false); } public void testGetRestrictBackgroundStatus_disabled() throws Exception { - removeRestrictBackgroundWhitelist(mUid); - assertRestrictBackgroundStatusDisabled(); - // From the app's point of view, nothing changed, it still have access - assertRestrictBackgroundChangedNotReceived(); - - // Sanity check: make sure status is always disabled, never whitelisted - addRestrictBackgroundWhitelist(mUid); - assertRestrictBackgroundStatusDisabled(); - assertRestrictBackgroundChangedNotReceived(); - } - - public void testGetRestrictBackgroundStatus_whitelisted() throws Exception { - setRestrictBackground(true); - assertRestrictBackgroundChangedReceivedOnce(); - - addRestrictBackgroundWhitelist(mUid); - assertRestrictBackgroundStatusWhitelisted(); - assertRestrictBackgroundChangedReceivedTwice(); - } - - public void testGetRestrictBackgroundStatus_enabled() throws Exception { - setRestrictBackground(true); - assertRestrictBackgroundChangedReceivedOnce(); - - removeRestrictBackgroundWhitelist(mUid); - assertRestrictBackgroundStatusEnabled(); - assertRestrictBackgroundChangedReceivedOnce(); - } - - public void testGetRestrictBackgroundStatus_uninstall() throws Exception { - addRestrictBackgroundWhitelist(mUid); - assertRestrictBackgroundWhitelist(mUid, true); - - uninstallPackage(TEST_PKG, true); - assertPackageUninstalled(TEST_PKG); - assertRestrictBackgroundWhitelist(mUid, false); - - installPackage(TEST_APK); - final int newUid = getUid(TEST_PKG); - assertRestrictBackgroundWhitelist(mUid, false); - assertRestrictBackgroundWhitelist(newUid, false); - } - - /** - * Starts a service that will register a broadcast receiver to receive - * {@code RESTRICT_BACKGROUND_CHANGE} intents. - *

- * The service must run in a separate app because otherwise it would be killed every time - * {@link #runDeviceTests(String, String)} is executed. - */ - private void startBroadcastReceiverService() throws DeviceNotAvailableException { - runCommand("am startservice " + TEST_APP2_PKG + "/.MyService"); - } - - private void assertRestrictBackgroundStatusDisabled() throws DeviceNotAvailableException { runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", "testGetRestrictBackgroundStatus_disabled"); } - private void assertRestrictBackgroundStatusWhitelisted() throws DeviceNotAvailableException { + public void testGetRestrictBackgroundStatus_whitelisted() throws Exception { runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", "testGetRestrictBackgroundStatus_whitelisted"); } - private void assertRestrictBackgroundStatusEnabled() throws DeviceNotAvailableException { + public void testGetRestrictBackgroundStatus_enabled() throws Exception { runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", "testGetRestrictBackgroundStatus_enabled"); } - private void assertRestrictBackgroundChangedNotReceived() throws DeviceNotAvailableException { - runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", - "testRestrictBackgroundChangedNotReceived"); - } + public void testGetRestrictBackgroundStatus_uninstall() throws Exception { + final int oldUid = getUid(TEST_PKG); + testGetRestrictBackgroundStatus_whitelisted(); - private void assertRestrictBackgroundChangedReceivedOnce() throws DeviceNotAvailableException { - runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", - "testRestrictBackgroundChangedReceivedOnce"); - } + uninstallPackage(TEST_PKG, true); + assertPackageUninstalled(TEST_PKG); + assertRestrictBackgroundWhitelist(oldUid, false); - private void assertRestrictBackgroundChangedReceivedTwice() throws DeviceNotAvailableException { - runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", - "testRestrictBackgroundChangedReceivedTwice"); - } - - private void addRestrictBackgroundWhitelist(int uid) throws Exception { - runCommand("cmd netpolicy add restrict-background-whitelist " + uid); - assertRestrictBackgroundWhitelist(uid, true); - } - - private void removeRestrictBackgroundWhitelist(int uid) throws Exception { - runCommand("cmd netpolicy remove restrict-background-whitelist " + uid); - assertRestrictBackgroundWhitelist(uid, false); + installPackage(TEST_APK); + final int newUid = getUid(TEST_PKG); + assertRestrictBackgroundWhitelist(oldUid, false); + assertRestrictBackgroundWhitelist(newUid, false); } private void assertRestrictBackgroundWhitelist(int uid, boolean expected) throws Exception { @@ -163,32 +84,4 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC fail("whitelist check for uid " + uid + " failed: expected " + expected + ", got " + actual); } - - private void setWifiMeteredStatus(boolean metered) throws DeviceNotAvailableException { - mWifiHelper.enableWifi(); - // TODO: if it's not guaranteed the device has wi-fi, we need to change the tests - // to make the actual verification of restrictions optional. - final String netId = mWifiHelper.getSSID(); - assertNotNull("null SSID", netId); - assertFalse("empty SSID", netId.trim().isEmpty()); - - Log.i(TAG, "Setting wi-fi network " + netId + " metered status to " + metered); - final String setCommand = "cmd netpolicy set metered-network " + netId + " "+ metered; - final String result = runCommand(setCommand); - assertTrue("Command '" + setCommand + "' failed: " + result, result.trim().isEmpty()); - - // Sanity check. - final String newStatus = runCommand("cmd netpolicy get metered-network " + netId); - assertEquals("Metered status of wi-fi network " + netId + " not set properly", - newStatus.trim(), Boolean.toString(metered)); - } - - private void setRestrictBackground(boolean enabled) throws DeviceNotAvailableException { - runCommand("cmd netpolicy set restrict-background " + enabled); - final String output = runCommand("cmd netpolicy get restrict-background ").trim(); - final String expectedSuffix = enabled ? "enabled" : "disabled"; - // TODO: use MoreAsserts? - assertTrue("output '" + output + "' should end with '" + expectedSuffix + "'", - output.endsWith(expectedSuffix)); - } }