Update ConnOnActivityStartTest to be hermetic.
Bug: 38432755
Test: runtest -x services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java
Change-Id: Ie847ec0a202021a2b2cf16bb2d720650c9ee847d
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 7959e39..ac4423d 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -2647,6 +2647,42 @@
return failures;
}
+ @Override
+ public boolean isNetworkRestricted(int uid) {
+ mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+ return isNetworkRestrictedInternal(uid);
+ }
+
+ private boolean isNetworkRestrictedInternal(int uid) {
+ synchronized (mRulesLock) {
+ if (getFirewallChainState(FIREWALL_CHAIN_STANDBY)
+ && mUidFirewallStandbyRules.get(uid) == FIREWALL_RULE_DENY) {
+ if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of app standby mode");
+ return true;
+ }
+ if (getFirewallChainState(FIREWALL_CHAIN_DOZABLE)
+ && mUidFirewallDozableRules.get(uid) != FIREWALL_RULE_ALLOW) {
+ if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of device idle mode");
+ return true;
+ }
+ if (getFirewallChainState(FIREWALL_CHAIN_POWERSAVE)
+ && mUidFirewallPowerSaveRules.get(uid) != FIREWALL_RULE_ALLOW) {
+ if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of power saver mode");
+ return true;
+ }
+ if (mUidRejectOnMetered.get(uid)) {
+ if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of no metered data"
+ + " in the background");
+ return true;
+ }
+ if (mDataSaverMode && !mUidAllowOnMetered.get(uid)) {
+ if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of data saver mode");
+ return true;
+ }
+ return false;
+ }
+ }
+
private void setFirewallChainState(int chain, boolean state) {
synchronized (mRulesLock) {
mFirewallChainStates.put(chain, state);
@@ -2663,33 +2699,7 @@
class LocalService extends NetworkManagementInternal {
@Override
public boolean isNetworkRestrictedForUid(int uid) {
- synchronized (mRulesLock) {
- if (getFirewallChainState(FIREWALL_CHAIN_STANDBY)
- && mUidFirewallStandbyRules.get(uid) == FIREWALL_RULE_DENY) {
- if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of app standby mode");
- return true;
- }
- if (getFirewallChainState(FIREWALL_CHAIN_DOZABLE)
- && mUidFirewallDozableRules.get(uid) != FIREWALL_RULE_ALLOW) {
- if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of device idle mode");
- return true;
- }
- if (getFirewallChainState(FIREWALL_CHAIN_POWERSAVE)
- && mUidFirewallPowerSaveRules.get(uid) != FIREWALL_RULE_ALLOW) {
- if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of power saver mode");
- return true;
- }
- if (mUidRejectOnMetered.get(uid)) {
- if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of no metered data"
- + " in the background");
- return true;
- }
- if (mDataSaverMode && !mUidAllowOnMetered.get(uid)) {
- if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of data saver mode");
- return true;
- }
- return false;
- }
+ return isNetworkRestrictedInternal(uid);
}
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index aabb245..0072ba4 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -4315,6 +4315,47 @@
}
}
+ @Override
+ public boolean isUidNetworkingBlocked(int uid, boolean isNetworkMetered) {
+ mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
+ return isUidNetworkingBlockedInternal(uid, isNetworkMetered);
+ }
+
+ private boolean isUidNetworkingBlockedInternal(int uid, boolean isNetworkMetered) {
+ final int uidRules;
+ final boolean isBackgroundRestricted;
+ synchronized (mUidRulesFirstLock) {
+ uidRules = mUidRules.get(uid, RULE_NONE);
+ isBackgroundRestricted = mRestrictBackground;
+ }
+ if (hasRule(uidRules, RULE_REJECT_ALL)) {
+ if (LOGV) logUidStatus(uid, "blocked by power restrictions");
+ return true;
+ }
+ if (!isNetworkMetered) {
+ if (LOGV) logUidStatus(uid, "allowed on unmetered network");
+ return false;
+ }
+ if (hasRule(uidRules, RULE_REJECT_METERED)) {
+ if (LOGV) logUidStatus(uid, "blacklisted on metered network");
+ return true;
+ }
+ if (hasRule(uidRules, RULE_ALLOW_METERED)) {
+ if (LOGV) logUidStatus(uid, "whitelisted on metered network");
+ return false;
+ }
+ if (hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED)) {
+ if (LOGV) logUidStatus(uid, "temporary whitelisted on metered network");
+ return false;
+ }
+ if (isBackgroundRestricted) {
+ if (LOGV) logUidStatus(uid, "blocked when background is restricted");
+ return true;
+ }
+ if (LOGV) logUidStatus(uid, "allowed by default");
+ return false;
+ }
+
private class NetworkPolicyManagerInternalImpl extends NetworkPolicyManagerInternal {
@Override
@@ -4352,42 +4393,11 @@
*/
@Override
public boolean isUidNetworkingBlocked(int uid, String ifname) {
- final int uidRules;
- final boolean isBackgroundRestricted;
final boolean isNetworkMetered;
- synchronized (mUidRulesFirstLock) {
- uidRules = mUidRules.get(uid, RULE_NONE);
- isBackgroundRestricted = mRestrictBackground;
- synchronized (mNetworkPoliciesSecondLock) {
- isNetworkMetered = mMeteredIfaces.contains(ifname);
- }
+ synchronized (mNetworkPoliciesSecondLock) {
+ isNetworkMetered = mMeteredIfaces.contains(ifname);
}
- if (hasRule(uidRules, RULE_REJECT_ALL)) {
- if (LOGV) logUidStatus(uid, "blocked by power restrictions");
- return true;
- }
- if (!isNetworkMetered) {
- if (LOGV) logUidStatus(uid, "allowed on unmetered network");
- return false;
- }
- if (hasRule(uidRules, RULE_REJECT_METERED)) {
- if (LOGV) logUidStatus(uid, "blacklisted on metered network");
- return true;
- }
- if (hasRule(uidRules, RULE_ALLOW_METERED)) {
- if (LOGV) logUidStatus(uid, "whitelisted on metered network");
- return false;
- }
- if (hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED)) {
- if (LOGV) logUidStatus(uid, "temporary whitelisted on metered network");
- return false;
- }
- if (isBackgroundRestricted) {
- if (LOGV) logUidStatus(uid, "blocked when background is restricted");
- return true;
- }
- if (LOGV) logUidStatus(uid, "allowed by default");
- return false;
+ return isUidNetworkingBlockedInternal(uid, isNetworkMetered);
}
}
diff --git a/services/tests/servicestests/res/raw/conntestapp b/services/tests/servicestests/res/raw/conntestapp
index 6093303..e993164 100644
--- a/services/tests/servicestests/res/raw/conntestapp
+++ b/services/tests/servicestests/res/raw/conntestapp
Binary files differ
diff --git a/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java b/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java
index f02cf51..5b4c10f 100644
--- a/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java
@@ -20,7 +20,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -37,8 +36,6 @@
import android.content.pm.IPackageDeleteObserver;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.Bundle;
@@ -101,19 +98,16 @@
private static final long WAIT_FOR_INSTALL_TIMEOUT_MS = 2000; // 2 sec
- private static final long NETWORK_CHECK_TIMEOUT_MS = 6000; // 6 sec
+ private static final long NETWORK_CHECK_TIMEOUT_MS = 4000; // 4 sec
private static final long SCREEN_ON_DELAY_MS = 500; // 0.5 sec
- private static final String NETWORK_STATUS_SEPARATOR = "\\|";
-
private static final int REPEAT_TEST_COUNT = 5;
private static Context mContext;
private static UiDevice mUiDevice;
private static int mTestPkgUid;
private static BatteryManager mBatteryManager;
- private static ConnectivityManager mConnectivityManager;
@BeforeClass
public static void setUpOnce() throws Exception {
@@ -126,8 +120,6 @@
mTestPkgUid = mContext.getPackageManager().getPackageUid(TEST_PKG, 0);
mBatteryManager = (BatteryManager) mContext.getSystemService(Context.BATTERY_SERVICE);
- mConnectivityManager = (ConnectivityManager) mContext.getSystemService(
- Context.CONNECTIVITY_SERVICE);
}
@AfterClass
@@ -144,9 +136,6 @@
@Test
public void testStartActivity_batterySaver() throws Exception {
- if (!isNetworkAvailable()) {
- fail("Device doesn't have network connectivity");
- }
setBatterySaverMode(true);
try {
testConnOnActivityStart("testStartActivity_batterySaver");
@@ -157,9 +146,6 @@
@Test
public void testStartActivity_dataSaver() throws Exception {
- if (!isNetworkAvailable()) {
- fail("Device doesn't have network connectivity");
- }
setDataSaverMode(true);
try {
testConnOnActivityStart("testStartActivity_dataSaver");
@@ -170,9 +156,6 @@
@Test
public void testStartActivity_dozeMode() throws Exception {
- if (!isNetworkAvailable()) {
- fail("Device doesn't have network connectivity");
- }
setDozeMode(true);
try {
testConnOnActivityStart("testStartActivity_dozeMode");
@@ -183,9 +166,6 @@
@Test
public void testStartActivity_appStandby() throws Exception {
- if (!isNetworkAvailable()) {
- fail("Device doesn't have network connectivity");
- }
try{
turnBatteryOff();
setAppIdle(true);
@@ -200,9 +180,6 @@
@Test
public void testStartActivity_backgroundRestrict() throws Exception {
- if (!isNetworkAvailable()) {
- fail("Device doesn't have network connectivity");
- }
updateRestrictBackgroundBlacklist(true);
try {
testConnOnActivityStart("testStartActivity_backgroundRestrict");
@@ -347,11 +324,6 @@
+ maxTries + " attempts. Last result: '" + result + "'");
}
- private boolean isNetworkAvailable() throws Exception {
- final NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo();
- return networkInfo != null && networkInfo.isConnected();
- }
-
private void startActivityAndCheckNetworkAccess() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
final Intent launchIntent = new Intent().setComponent(
@@ -361,15 +333,15 @@
extras.putBinder(EXTRA_NETWORK_STATE_OBSERVER, new INetworkStateObserver.Stub() {
@Override
public void onNetworkStateChecked(String resultData) {
- errors[0] = checkForAvailability(resultData);
+ errors[0] = resultData;
latch.countDown();
}
});
launchIntent.putExtras(extras);
mContext.startActivity(launchIntent);
if (latch.await(NETWORK_CHECK_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
- if (!errors[0].isEmpty()) {
- fail("Network not available for test app " + mTestPkgUid);
+ if (errors[0] != null) {
+ fail("Network not available for test app " + mTestPkgUid + ". " + errors[0]);
}
} else {
fail("Timed out waiting for network availability status from test app " + mTestPkgUid);
@@ -381,43 +353,6 @@
.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
mContext.sendBroadcast(finishIntent);
}
-
- private String checkForAvailability(String resultData) {
- if (resultData == null) {
- assertNotNull("Network status from app2 is null, Uid: " + mTestPkgUid, resultData);
- }
- // Network status format is described on MyBroadcastReceiver.checkNetworkStatus()
- final String[] parts = resultData.split(NETWORK_STATUS_SEPARATOR);
- assertEquals("Wrong network status: " + resultData + ", Uid: " + mTestPkgUid,
- 5, parts.length); // Sanity check
- final NetworkInfo.State state = parts[0].equals("null")
- ? null : NetworkInfo.State.valueOf(parts[0]);
- final NetworkInfo.DetailedState detailedState = parts[1].equals("null")
- ? null : NetworkInfo.DetailedState.valueOf(parts[1]);
- final boolean connected = Boolean.valueOf(parts[2]);
- final String connectionCheckDetails = parts[3];
- final String networkInfo = parts[4];
-
- final StringBuilder errors = new StringBuilder();
- final NetworkInfo.State expectedState = NetworkInfo.State.CONNECTED;
- final NetworkInfo.DetailedState expectedDetailedState = NetworkInfo.DetailedState.CONNECTED;
-
- if (true != connected) {
- errors.append(String.format("External site connection failed: expected %s, got %s\n",
- true, connected));
- }
- if (expectedState != state || expectedDetailedState != detailedState) {
- errors.append(String.format("Connection state mismatch: expected %s/%s, got %s/%s\n",
- expectedState, expectedDetailedState, state, detailedState));
- }
-
- if (errors.length() > 0) {
- errors.append("\tnetworkInfo: " + networkInfo + "\n");
- errors.append("\tconnectionCheckDetails: " + connectionCheckDetails + "\n");
- }
- return errors.toString();
- }
-
private static void installAppAndAssertInstalled() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
final int[] result = {PackageInstaller.STATUS_SUCCESS};
diff --git a/services/tests/servicestests/test-apps/ConnTestApp/Android.mk b/services/tests/servicestests/test-apps/ConnTestApp/Android.mk
index 02afe83..030a709 100644
--- a/services/tests/servicestests/test-apps/ConnTestApp/Android.mk
+++ b/services/tests/servicestests/test-apps/ConnTestApp/Android.mk
@@ -17,7 +17,6 @@
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
-LOCAL_SDK_VERSION := current
LOCAL_STATIC_JAVA_LIBRARIES := servicestests-aidl
LOCAL_SRC_FILES := $(call all-subdir-java-files)
diff --git a/services/tests/servicestests/test-apps/ConnTestApp/AndroidManifest.xml b/services/tests/servicestests/test-apps/ConnTestApp/AndroidManifest.xml
index 0da3562..6671410 100644
--- a/services/tests/servicestests/test-apps/ConnTestApp/AndroidManifest.xml
+++ b/services/tests/servicestests/test-apps/ConnTestApp/AndroidManifest.xml
@@ -17,8 +17,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.servicestests.apps.conntestapp">
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
+ <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
<application>
<activity android:name=".ConnTestActivity"
diff --git a/services/tests/servicestests/test-apps/ConnTestApp/src/com/android/servicestests/apps/conntestapp/ConnTestActivity.java b/services/tests/servicestests/test-apps/ConnTestApp/src/com/android/servicestests/apps/conntestapp/ConnTestActivity.java
index 11ebfca..c5c7add 100644
--- a/services/tests/servicestests/test-apps/ConnTestApp/src/com/android/servicestests/apps/conntestapp/ConnTestActivity.java
+++ b/services/tests/servicestests/test-apps/ConnTestApp/src/com/android/servicestests/apps/conntestapp/ConnTestActivity.java
@@ -21,19 +21,17 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
+import android.net.INetworkPolicyManager;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.os.INetworkManagementService;
+import android.os.Process;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.util.Log;
import com.android.servicestests.aidl.INetworkStateObserver;
-import java.net.HttpURLConnection;
-import java.net.URL;
-
public class ConnTestActivity extends Activity {
private static final String TAG = ConnTestActivity.class.getSimpleName();
@@ -41,10 +39,6 @@
private static final String ACTION_FINISH_ACTIVITY = TEST_PKG + ".FINISH";
private static final String EXTRA_NETWORK_STATE_OBSERVER = TEST_PKG + ".observer";
- private static final int NETWORK_TIMEOUT_MS = 5 * 1000;
-
- private static final String NETWORK_STATUS_TEMPLATE = "%s|%s|%s|%s|%s";
-
private BroadcastReceiver finishCommandReceiver = null;
@Override
@@ -84,7 +78,7 @@
if (observer != null) {
AsyncTask.execute(() -> {
try {
- observer.onNetworkStateChecked(checkNetworkStatus(ConnTestActivity.this));
+ observer.onNetworkStateChecked(checkNetworkStatus());
} catch (RemoteException e) {
Log.e(TAG, "Error occured while notifying the observer: " + e);
}
@@ -93,78 +87,25 @@
}
/**
- * Checks whether the network is available and return a string which can then be send as a
- * result data for the ordered broadcast.
+ * Checks whether the network is restricted.
*
- * <p>
- * The string has the following format:
- *
- * <p><pre><code>
- * NetinfoState|NetinfoDetailedState|RealConnectionCheck|RealConnectionCheckDetails|Netinfo
- * </code></pre>
- *
- * <p>Where:
- *
- * <ul>
- * <li>{@code NetinfoState}: enum value of {@link NetworkInfo.State}.
- * <li>{@code NetinfoDetailedState}: enum value of {@link NetworkInfo.DetailedState}.
- * <li>{@code RealConnectionCheck}: boolean value of a real connection check (i.e., an attempt
- * to access an external website.
- * <li>{@code RealConnectionCheckDetails}: if HTTP output core or exception string of the real
- * connection attempt
- * <li>{@code Netinfo}: string representation of the {@link NetworkInfo}.
- * </ul>
- *
- * For example, if the connection was established fine, the result would be something like:
- * <p><pre><code>
- * CONNECTED|CONNECTED|true|200|[type: WIFI[], state: CONNECTED/CONNECTED, reason: ...]
- * </code></pre>
+ * @return null if network is not restricted, otherwise an error message.
*/
- private String checkNetworkStatus(Context context) {
- final ConnectivityManager cm =
- (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
- final String address = "http://example.com";
- final NetworkInfo networkInfo = cm.getActiveNetworkInfo();
- Log.d(TAG, "Running checkNetworkStatus() on thread "
- + Thread.currentThread().getName() + " for UID " + getUid(context)
- + "\n\tactiveNetworkInfo: " + networkInfo + "\n\tURL: " + address);
- boolean checkStatus = false;
- String checkDetails = "N/A";
+ private String checkNetworkStatus() {
+ final INetworkManagementService nms = INetworkManagementService.Stub.asInterface(
+ ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
+ final INetworkPolicyManager npms = INetworkPolicyManager.Stub.asInterface(
+ ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
try {
- final URL url = new URL(address);
- final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setReadTimeout(NETWORK_TIMEOUT_MS);
- conn.setConnectTimeout(NETWORK_TIMEOUT_MS / 2);
- conn.setRequestMethod("GET");
- conn.setDoInput(true);
- conn.connect();
- final int response = conn.getResponseCode();
- checkStatus = true;
- checkDetails = "HTTP response for " + address + ": " + response;
- } catch (Exception e) {
- checkStatus = false;
- checkDetails = "Exception getting " + address + ": " + e;
- }
- Log.d(TAG, checkDetails);
- final String state, detailedState;
- if (networkInfo != null) {
- state = networkInfo.getState().name();
- detailedState = networkInfo.getDetailedState().name();
- } else {
- state = detailedState = "null";
- }
- final String status = String.format(NETWORK_STATUS_TEMPLATE, state, detailedState,
- Boolean.valueOf(checkStatus), checkDetails, networkInfo);
- Log.d(TAG, "Offering " + status);
- return status;
- }
-
- private int getUid(Context context) {
- final String packageName = context.getPackageName();
- try {
- return context.getPackageManager().getPackageUid(packageName, 0);
- } catch (PackageManager.NameNotFoundException e) {
- throw new IllegalStateException("Could not get UID for " + packageName, e);
+ final boolean restrictedByFwRules = nms.isNetworkRestricted(Process.myUid());
+ final boolean restrictedByUidRules = npms.isUidNetworkingBlocked(Process.myUid(), true);
+ if (restrictedByFwRules || restrictedByUidRules) {
+ return "Network is restricted by fwRules: " + restrictedByFwRules
+ + " and uidRules: " + restrictedByUidRules;
+ }
+ return null;
+ } catch (RemoteException e) {
+ return "Error talking to system server: " + e;
}
}
}
\ No newline at end of file