Merge "Move the NetworkStack tests to unit/ to add an integration test."
diff --git a/Android.bp b/Android.bp
index 9c8efe6..e15526a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -98,8 +98,6 @@
     optimize: {
         proguard_flags_files: ["proguard.flags"],
     },
-    // The permission configuration *must* be included to ensure security of the device
-    required: ["NetworkPermissionConfig"],
 }
 
 // Non-updatable network stack running in the system server process for devices not using the module
@@ -108,6 +106,10 @@
     defaults: ["NetworkStackAppCommon"],
     certificate: "platform",
     manifest: "AndroidManifest_InProcess.xml",
+    // InProcessNetworkStack is a replacement for NetworkStack
+    overrides: ["NetworkStack"],
+    // The permission configuration *must* be included to ensure security of the device
+    required: ["PlatformNetworkPermissionConfig"],
 }
 
 // Updatable network stack packaged as an application
@@ -117,6 +119,8 @@
     certificate: "networkstack",
     manifest: "AndroidManifest.xml",
     use_embedded_native_libs: true,
+    // The permission configuration *must* be included to ensure security of the device
+    required: ["NetworkPermissionConfig"],
 }
 
 genrule {
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 3b39cee..de45784 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -37,7 +37,9 @@
     <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
     <!-- Signature permission defined in NetworkStackStub -->
     <uses-permission android:name="android.permission.MAINLINE_NETWORK_STACK" />
-    <application android:extractNativeLibs="false">
+    <application
+        android:extractNativeLibs="false"
+        android:persistent="true">
         <service android:name="com.android.server.NetworkStackService">
             <intent-filter>
                 <action android:name="android.net.INetworkStackConnector"/>
diff --git a/src/com/android/server/NetworkStackService.java b/src/com/android/server/NetworkStackService.java
index a6d7484..c394d4c 100644
--- a/src/com/android/server/NetworkStackService.java
+++ b/src/com/android/server/NetworkStackService.java
@@ -62,6 +62,7 @@
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * Android service used to start the network stack when bound to via an intent.
@@ -117,6 +118,15 @@
         @GuardedBy("mValidationLogs")
         private final ArrayDeque<SharedLog> mValidationLogs = new ArrayDeque<>(MAX_VALIDATION_LOGS);
 
+        private static final int VERSION_UNKNOWN = 0;
+        private static final String DUMPSYS_ARG_VERSION = "version";
+
+        /** Version of the AIDL interfaces observed on the system */
+        private final AtomicInteger mSystemAidlVersion = new AtomicInteger(VERSION_UNKNOWN);
+
+        /** Whether different versions have been observed on interfaces provided by the system */
+        private volatile boolean mConflictingSystemAidlVersions = false;
+
         private SharedLog addValidationLogs(Network network, String name) {
             final SharedLog log = new SharedLog(NUM_VALIDATION_LOG_LINES, network + " - " + name);
             synchronized (mValidationLogs) {
@@ -143,6 +153,13 @@
             }
         }
 
+        private void updateSystemAidlVersion(final int version) {
+            final int previousVersion = mSystemAidlVersion.getAndSet(version);
+            if (previousVersion != VERSION_UNKNOWN && previousVersion != version) {
+                mConflictingSystemAidlVersions = true;
+            }
+        }
+
         @NonNull
         private final SharedLog mLog = new SharedLog(TAG);
 
@@ -150,6 +167,7 @@
         public void makeDhcpServer(@NonNull String ifName, @NonNull DhcpServingParamsParcel params,
                 @NonNull IDhcpServerCallbacks cb) throws RemoteException {
             checkNetworkStackCallingPermission();
+            updateSystemAidlVersion(cb.getInterfaceVersion());
             final DhcpServer server;
             try {
                 server = new DhcpServer(
@@ -171,6 +189,7 @@
         @Override
         public void makeNetworkMonitor(Network network, String name, INetworkMonitorCallbacks cb)
                 throws RemoteException {
+            updateSystemAidlVersion(cb.getInterfaceVersion());
             final SharedLog log = addValidationLogs(network, name);
             final NetworkMonitor nm = new NetworkMonitor(mContext, cb, network, log);
             cb.onNetworkMonitorCreated(new NetworkMonitorImpl(nm));
@@ -178,6 +197,7 @@
 
         @Override
         public void makeIpClient(String ifName, IIpClientCallbacks cb) throws RemoteException {
+            updateSystemAidlVersion(cb.getInterfaceVersion());
             final IpClient ipClient = new IpClient(mContext, ifName, cb, mObserverRegistry, this);
 
             synchronized (mIpClients) {
@@ -202,6 +222,7 @@
         @Override
         public void fetchIpMemoryStore(@NonNull final IIpMemoryStoreCallbacks cb)
                 throws RemoteException {
+            updateSystemAidlVersion(cb.getInterfaceVersion());
             cb.onIpMemoryStoreFetched(mIpMemoryStoreService);
         }
 
@@ -209,6 +230,11 @@
         protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout,
                 @Nullable String[] args) {
             checkDumpPermission();
+            if (args != null && args.length >= 1 && DUMPSYS_ARG_VERSION.equals(args[0])) {
+                dumpVersion(fout);
+                return;
+            }
+
             final IndentingPrintWriter pw = new IndentingPrintWriter(fout, "  ");
             pw.println("NetworkStack logs:");
             mLog.dump(fd, pw, args);
@@ -252,6 +278,15 @@
             }
         }
 
+        /**
+         * Dump version information of the module and detected system version.
+         */
+        private void dumpVersion(@NonNull PrintWriter fout) {
+            fout.println("NetworkStackConnector: " + this.VERSION);
+            fout.println("SystemServer: " + mSystemAidlVersion);
+            fout.println("SystemServerConflicts: " + mConflictingSystemAidlVersions);
+        }
+
         @Override
         public int getInterfaceVersion() {
             return this.VERSION;