Add configuration object and builder for creating tun/tap interfaces

This change is finally (!) adding a builder class for creating tun/tap
interfaces for testing.

The various create*Interface() methods which are not marked as
@SystemApi can be removed after moving existing tests over to the new
API.

Bug: 237694424
Test: TH
Change-Id: I10eff755ebda4e2ef2550a50a3bfd1543a21e5b0
diff --git a/framework/src/android/net/TestNetworkManager.java b/framework/src/android/net/TestNetworkManager.java
index 416c6de..caeef48 100644
--- a/framework/src/android/net/TestNetworkManager.java
+++ b/framework/src/android/net/TestNetworkManager.java
@@ -23,8 +23,10 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -337,4 +339,110 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Represents a request to create a tun/tap interface for testing.
+     *
+     * @hide
+     */
+    public static class TestInterfaceRequest {
+        public final boolean isTun;
+        public final boolean hasCarrier;
+        public final boolean bringUp;
+        public final boolean disableIpv6ProvDelay;
+        @Nullable public final String ifname;
+        public final LinkAddress[] linkAddresses;
+
+        private TestInterfaceRequest(boolean isTun, boolean hasCarrier, boolean bringUp,
+                boolean disableProvDelay, @Nullable String ifname, LinkAddress[] linkAddresses) {
+            this.isTun = isTun;
+            this.hasCarrier = hasCarrier;
+            this.bringUp = bringUp;
+            this.disableIpv6ProvDelay = disableProvDelay;
+            this.ifname = ifname;
+            this.linkAddresses = linkAddresses;
+        }
+
+        /**
+         * Builder class for TestInterfaceRequest
+         *
+         * Defaults to a tap interface with carrier that has been brought up.
+         */
+        public static class Builder {
+            private boolean mIsTun = false;
+            private boolean mHasCarrier = true;
+            private boolean mBringUp = true;
+            private boolean mDisableIpv6ProvDelay = false;
+            @Nullable private String mIfname;
+            private List<LinkAddress> mLinkAddresses = new ArrayList<>();
+
+            /** Create tun interface. */
+            public Builder setTun() {
+                mIsTun = true;
+                return this;
+            }
+
+            /** Create tap interface. */
+            public Builder setTap() {
+                mIsTun = false;
+                return this;
+            }
+
+            /** Configure whether the interface has carrier. */
+            public Builder setHasCarrier(boolean hasCarrier) {
+                mHasCarrier = hasCarrier;
+                return this;
+            }
+
+            /** Configure whether the interface should be brought up. */
+            public Builder setBringUp(boolean bringUp) {
+                mBringUp = bringUp;
+                return this;
+            }
+
+            /** Disable DAD and RS delay. */
+            public Builder setDisableIpv6ProvisioningDelay(boolean disableProvDelay) {
+                mDisableIpv6ProvDelay = disableProvDelay;
+                return this;
+            }
+
+            /** Set the interface name. */
+            public Builder setInterfaceName(@Nullable String ifname) {
+                mIfname = ifname;
+                return this;
+            }
+
+            /** The addresses to configure on the interface. */
+            public Builder addLinkAddress(LinkAddress la) {
+                mLinkAddresses.add(la);
+                return this;
+            }
+
+            /** Build TestInterfaceRequest */
+            public TestInterfaceRequest build() {
+                return new TestInterfaceRequest(mIsTun, mHasCarrier, mBringUp,
+                        mDisableIpv6ProvDelay, mIfname, mLinkAddresses.toArray(new LinkAddress[0]));
+            }
+        }
+    }
+
+    /**
+     * Create a TestNetworkInterface (tun or tap) for testing purposes.
+     *
+     * @param request The request describing the interface to create.
+     * @return A TestNetworkInterface representing the underlying tun/tap interface. Close the
+     *         contained ParcelFileDescriptor to tear down the tun/tap interface.
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS)
+    @NonNull
+    public TestNetworkInterface createTestInterface(@NonNull TestInterfaceRequest request) {
+        try {
+            // TODO: Make TestInterfaceRequest parcelable and pass it instead.
+            return mService.createInterface(request.isTun, request.hasCarrier, request.bringUp,
+                    request.disableIpv6ProvDelay, request.linkAddresses, request.ifname);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }