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