Merge "Remove @TestApi from @SystemApi symbols"
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 0def8b1..8fd2995 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -897,6 +897,18 @@
     }
 
     /**
+     * @hide
+     * TODO: Expose for SystemServer when becomes a module.
+     */
+    public void systemReady() {
+        try {
+            mService.systemReady();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Checks if a given type uses the cellular data connection.
      * This should be replaced in the future by a network property.
      * @param networkType the type to check
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index d7f178c..059ec28 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -233,4 +233,6 @@
 
     void simulateDataStall(int detectionMethod, long timestampMillis, in Network network,
                 in PersistableBundle extras);
+
+    void systemReady();
 }
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 3e41e57..616ccbe 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -21,7 +21,6 @@
 import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.net.util.LinkPropertiesUtils;
-import android.net.util.LinkPropertiesUtils.CompareResult;
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -1642,78 +1641,6 @@
     }
 
     /**
-     * Compares the DNS addresses in this LinkProperties with another
-     * LinkProperties, examining only DNS addresses on the base link.
-     *
-     * @param target a LinkProperties with the new list of dns addresses
-     * @return the differences between the DNS addresses.
-     * @hide
-     */
-    public @NonNull CompareResult<InetAddress> compareDnses(@Nullable LinkProperties target) {
-        /*
-         * Duplicate the InetAddresses into removed, we will be removing
-         * dns address which are common between mDnses and target
-         * leaving the addresses that are different. And dns address which
-         * are in target but not in mDnses are placed in the
-         * addedAddresses.
-         */
-        return new CompareResult<>(mDnses, target != null ? target.getDnsServers() : null);
-    }
-
-    /**
-     * Compares the validated private DNS addresses in this LinkProperties with another
-     * LinkProperties.
-     *
-     * @param target a LinkProperties with the new list of validated private dns addresses
-     * @return the differences between the DNS addresses.
-     * @hide
-     */
-    public @NonNull CompareResult<InetAddress> compareValidatedPrivateDnses(
-            @Nullable LinkProperties target) {
-        return new CompareResult<>(mValidatedPrivateDnses,
-                target != null ? target.getValidatedPrivateDnsServers() : null);
-    }
-
-    /**
-     * Compares all routes in this LinkProperties with another LinkProperties,
-     * examining both the the base link and all stacked links.
-     *
-     * @param target a LinkProperties with the new list of routes
-     * @return the differences between the routes.
-     * @hide
-     */
-    public @NonNull CompareResult<RouteInfo> compareAllRoutes(@Nullable LinkProperties target) {
-        /*
-         * Duplicate the RouteInfos into removed, we will be removing
-         * routes which are common between mRoutes and target
-         * leaving the routes that are different. And route address which
-         * are in target but not in mRoutes are placed in added.
-         */
-        return new CompareResult<>(getAllRoutes(), target != null ? target.getAllRoutes() : null);
-    }
-
-    /**
-     * Compares all interface names in this LinkProperties with another
-     * LinkProperties, examining both the the base link and all stacked links.
-     *
-     * @param target a LinkProperties with the new list of interface names
-     * @return the differences between the interface names.
-     * @hide
-     */
-    public @NonNull CompareResult<String> compareAllInterfaceNames(
-            @Nullable LinkProperties target) {
-        /*
-         * Duplicate the interface names into removed, we will be removing
-         * interface names which are common between this and target
-         * leaving the interface names that are different. And interface names which
-         * are in target but not in this are placed in added.
-         */
-        return new CompareResult<>(getAllInterfaceNames(),
-                target != null ? target.getAllInterfaceNames() : null);
-    }
-
-
-    /**
      * Generate hashcode based on significant fields
      *
      * Equal objects must produce the same hash code, while unequal objects
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index 7d6135b..8d4c4e5 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -95,12 +95,11 @@
 {
     int optval_ignored = 0;
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
-    if (setsockopt(
-            fd, SOL_SOCKET, SO_DETACH_FILTER, &optval_ignored, sizeof(optval_ignored)) != 0) {
+    if (setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, &optval_ignored, sizeof(optval_ignored)) !=
+        0) {
         jniThrowExceptionFmt(env, "java/net/SocketException",
                 "setsockopt(SO_DETACH_FILTER): %s", strerror(errno));
     }
-
 }
 
 static jboolean android_net_utils_bindProcessToNetwork(JNIEnv *env, jobject thiz, jint netId)
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index d07a22d..cdc06ae 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1169,7 +1169,7 @@
 
         mMultipathPolicyTracker = new MultipathPolicyTracker(mContext, mHandler);
 
-        mDnsManager = new DnsManager(mContext, mDnsResolver, mSystemProperties);
+        mDnsManager = new DnsManager(mContext, mDnsResolver);
         registerPrivateDnsSettingsCallbacks();
     }
 
@@ -2300,10 +2300,21 @@
     }
 
     /**
-     * Called when the system is ready and ConnectivityService can initialize remaining components.
+     * Called by SystemServer through ConnectivityManager when the system is ready.
+     */
+    @Override
+    public void systemReady() {
+        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+            throw new SecurityException("Calling Uid is not system uid.");
+        }
+        systemReadyInternal();
+    }
+
+    /**
+     * Called when ConnectivityService can initialize remaining components.
      */
     @VisibleForTesting
-    public void systemReady() {
+    public void systemReadyInternal() {
         // Let PermissionMonitor#startMonitoring() running in the beginning of the systemReady
         // before MultipathPolicyTracker.start(). Since mApps in PermissionMonitor needs to be
         // populated first to ensure that listening network request which is sent by
diff --git a/services/core/java/com/android/server/ConnectivityServiceInitializer.java b/services/core/java/com/android/server/ConnectivityServiceInitializer.java
new file mode 100644
index 0000000..2bc8925
--- /dev/null
+++ b/services/core/java/com/android/server/ConnectivityServiceInitializer.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2020 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 com.android.server;
+
+import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
+import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
+
+import android.content.Context;
+import android.net.INetworkPolicyManager;
+import android.net.INetworkStatsService;
+import android.os.INetworkManagementService;
+import android.os.ServiceManager;
+import android.util.Log;
+
+/**
+ * Connectivity service initializer for core networking. This is called by system server to create
+ * a new instance of ConnectivityService.
+ */
+public final class ConnectivityServiceInitializer extends SystemService {
+    private static final String TAG = ConnectivityServiceInitializer.class.getSimpleName();
+    private final ConnectivityService mConnectivity;
+
+    public ConnectivityServiceInitializer(Context context) {
+        super(context);
+        // TODO: Define formal APIs to get the needed services.
+        mConnectivity = new ConnectivityService(context, getNetworkManagementService(),
+                getNetworkStatsService(), getNetworkPolicyManager());
+    }
+
+    @Override
+    public void onStart() {
+        Log.i(TAG, "Registering " + Context.CONNECTIVITY_SERVICE);
+        publishBinderService(Context.CONNECTIVITY_SERVICE, mConnectivity,
+                /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL);
+    }
+
+    private INetworkManagementService getNetworkManagementService() {
+        return INetworkManagementService.Stub.asInterface(
+               ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
+    }
+
+    private INetworkStatsService getNetworkStatsService() {
+        return INetworkStatsService.Stub.asInterface(
+                ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
+    }
+
+    private INetworkPolicyManager getNetworkPolicyManager() {
+        return INetworkPolicyManager.Stub.asInterface(
+                ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
+    }
+
+}
diff --git a/services/core/java/com/android/server/connectivity/DnsManager.java b/services/core/java/com/android/server/connectivity/DnsManager.java
index 271ec4e..c789186 100644
--- a/services/core/java/com/android/server/connectivity/DnsManager.java
+++ b/services/core/java/com/android/server/connectivity/DnsManager.java
@@ -237,7 +237,6 @@
     private final Context mContext;
     private final ContentResolver mContentResolver;
     private final IDnsResolver mDnsResolver;
-    private final MockableSystemProperties mSystemProperties;
     private final ConcurrentHashMap<Integer, PrivateDnsConfig> mPrivateDnsMap;
     // TODO: Replace the Map with SparseArrays.
     private final Map<Integer, PrivateDnsValidationStatuses> mPrivateDnsValidationMap;
@@ -249,11 +248,10 @@
     private int mMinSamples;
     private int mMaxSamples;
 
-    public DnsManager(Context ctx, IDnsResolver dnsResolver, MockableSystemProperties sp) {
+    public DnsManager(Context ctx, IDnsResolver dnsResolver) {
         mContext = ctx;
         mContentResolver = mContext.getContentResolver();
         mDnsResolver = dnsResolver;
-        mSystemProperties = sp;
         mPrivateDnsMap = new ConcurrentHashMap<>();
         mPrivateDnsValidationMap = new HashMap<>();
         mLinkPropertiesMap = new HashMap<>();
diff --git a/tests/net/Android.bp b/tests/net/Android.bp
index 0fe84ab..cd2dc04 100644
--- a/tests/net/Android.bp
+++ b/tests/net/Android.bp
@@ -59,6 +59,7 @@
         "mockito-target-minus-junit4",
         "net-tests-utils",
         "platform-test-annotations",
+        "service-connectivity",
         "services.core",
         "services.net",
     ],
diff --git a/tests/net/common/Android.bp b/tests/net/common/Android.bp
index 46d680f..373aac6 100644
--- a/tests/net/common/Android.bp
+++ b/tests/net/common/Android.bp
@@ -25,6 +25,7 @@
         "junit",
         "mockito-target-minus-junit4",
         "net-tests-utils",
+        "net-utils-framework-common",
         "platform-test-annotations",
     ],
     libs: [
diff --git a/tests/net/common/java/android/net/LinkPropertiesTest.java b/tests/net/common/java/android/net/LinkPropertiesTest.java
index 3c3076f..f52ab5b 100644
--- a/tests/net/common/java/android/net/LinkPropertiesTest.java
+++ b/tests/net/common/java/android/net/LinkPropertiesTest.java
@@ -32,7 +32,6 @@
 import static org.junit.Assert.fail;
 
 import android.net.LinkProperties.ProvisioningChange;
-import android.net.util.LinkPropertiesUtils.CompareResult;
 import android.os.Build;
 import android.system.OsConstants;
 import android.util.ArraySet;
@@ -41,6 +40,7 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.net.module.util.LinkPropertiesUtils.CompareResult;
 import com.android.testutils.DevSdkIgnoreRule;
 import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter;
 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
@@ -447,23 +447,21 @@
         assertEquals(3, lp.getRoutes().size());
         assertAllRoutesHaveInterface("wlan0", lp);
 
-        // Check comparisons work.
+        // Check routes are updated correctly when calling setInterfaceName.
         LinkProperties lp2 = new LinkProperties(lp);
         assertAllRoutesHaveInterface("wlan0", lp2);
-        // LinkProperties#compareAllRoutes exists both in R and before R, but the return type
-        // changed in R, so a test compiled with the R version of LinkProperties cannot run on Q.
-        if (isAtLeastR()) {
-            assertEquals(0, lp.compareAllRoutes(lp2).added.size());
-            assertEquals(0, lp.compareAllRoutes(lp2).removed.size());
-        }
+        final CompareResult<RouteInfo> cr1 =
+                new CompareResult<>(lp.getAllRoutes(), lp2.getAllRoutes());
+        assertEquals(0, cr1.added.size());
+        assertEquals(0, cr1.removed.size());
 
         lp2.setInterfaceName("p2p0");
         assertAllRoutesHaveInterface("p2p0", lp2);
         assertAllRoutesNotHaveInterface("wlan0", lp2);
-        if (isAtLeastR()) {
-            assertEquals(3, lp.compareAllRoutes(lp2).added.size());
-            assertEquals(3, lp.compareAllRoutes(lp2).removed.size());
-        }
+        final CompareResult<RouteInfo> cr2 =
+                new CompareResult<>(lp.getAllRoutes(), lp2.getAllRoutes());
+        assertEquals(3, cr2.added.size());
+        assertEquals(3, cr2.removed.size());
 
         // Remove route with incorrect interface, no route removed.
         lp.removeRoute(new RouteInfo(prefix2, null, null));
diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
index bc069e1..dba1856 100644
--- a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
+++ b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
@@ -167,7 +167,7 @@
         cm = ConnectivityManager(context, service)
         context.addMockSystemService(Context.CONNECTIVITY_SERVICE, cm)
 
-        service.systemReady()
+        service.systemReadyInternal()
     }
 
     private inner class TestConnectivityService(deps: Dependencies) : ConnectivityService(
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 862e552..998aee4 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -1246,7 +1246,7 @@
         // Create local CM before sending system ready so that we can answer
         // getSystemService() correctly.
         mCm = new WrappedConnectivityManager(InstrumentationRegistry.getContext(), mService);
-        mService.systemReady();
+        mService.systemReadyInternal();
         mockVpn(Process.myUid());
         mCm.bindProcessToNetwork(null);
 
diff --git a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
index 32bfa70..f5b85ca 100644
--- a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
@@ -98,7 +98,6 @@
 
     @Mock Context mCtx;
     @Mock IDnsResolver mMockDnsResolver;
-    @Mock MockableSystemProperties mSystemProperties;
 
     private void assertResolverOptionsEquals(
             @NonNull ResolverOptionsParcel actual,
@@ -137,7 +136,7 @@
         mContentResolver.addProvider(Settings.AUTHORITY,
                 new FakeSettingsProvider());
         when(mCtx.getContentResolver()).thenReturn(mContentResolver);
-        mDnsManager = new DnsManager(mCtx, mMockDnsResolver, mSystemProperties);
+        mDnsManager = new DnsManager(mCtx, mMockDnsResolver);
 
         // Clear the private DNS settings
         Settings.Global.putString(mContentResolver, PRIVATE_DNS_DEFAULT_MODE, "");