api,core: add LoadBalancer.Helper#createResolvingOobChannelBuilder api (#7136)

diff --git a/api/src/main/java/io/grpc/LoadBalancer.java b/api/src/main/java/io/grpc/LoadBalancer.java
index e97571c..d2ed1ad 100644
--- a/api/src/main/java/io/grpc/LoadBalancer.java
+++ b/api/src/main/java/io/grpc/LoadBalancer.java
@@ -1044,8 +1044,7 @@
      * {@link ManagedChannelBuilder#forTarget} for the format of a target string.
      *
      * <p>The target string will be resolved by a {@link NameResolver} created according to the
-     * target string.  The out-of-band channel doesn't have load-balancing.  If multiple addresses
-     * are resolved for the target, the first working address will be used.
+     * target string.
      *
      * <p>The LoadBalancer is responsible for closing unused OOB channels, and closing all OOB
      * channels within {@link #shutdown}.
@@ -1053,6 +1052,23 @@
      * @since 1.20.0
      */
     public ManagedChannel createResolvingOobChannel(String target) {
+      return createResolvingOobChannelBuilder(target).build();
+    }
+
+    /**
+     * Creates an out-of-band channel builder for LoadBalancer's own RPC needs, e.g., talking to an
+     * external load-balancer service, that is specified by a target string.  See the documentation
+     * on {@link ManagedChannelBuilder#forTarget} for the format of a target string.
+     *
+     * <p>The target string will be resolved by a {@link NameResolver} created according to the
+     * target string.
+     *
+     * <p>The LoadBalancer is responsible for closing unused OOB channels, and closing all OOB
+     * channels within {@link #shutdown}.
+     *
+     * @since 1.31.0
+     */
+    public ManagedChannelBuilder<?> createResolvingOobChannelBuilder(String target) {
       throw new UnsupportedOperationException("Not implemented");
     }
 
diff --git a/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java b/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java
index 05dee80..c23bd51 100644
--- a/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java
+++ b/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java
@@ -60,6 +60,7 @@
 import io.grpc.LoadBalancer.SubchannelPicker;
 import io.grpc.LoadBalancer.SubchannelStateListener;
 import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
 import io.grpc.Metadata;
 import io.grpc.MethodDescriptor;
 import io.grpc.NameResolver;
@@ -1260,7 +1261,7 @@
     }
 
     @Override
-    public ManagedChannel createResolvingOobChannel(String target) {
+    public ManagedChannelBuilder<?> createResolvingOobChannelBuilder(String target) {
       final class ResolvingOobChannelBuilder
           extends AbstractManagedChannelImplBuilder<ResolvingOobChannelBuilder> {
         int defaultPort = -1;
@@ -1278,6 +1279,19 @@
         protected ClientTransportFactory buildTransportFactory() {
           throw new UnsupportedOperationException();
         }
+
+        @Override
+        public ManagedChannel build() {
+          // TODO(creamsoup) prevent main channel to shutdown if oob channel is not terminated
+          return new ManagedChannelImpl(
+                  this,
+                  transportFactory,
+                  backoffPolicyProvider,
+                  balancerRpcExecutorPool,
+                  stopwatchSupplier,
+                  Collections.<ClientInterceptor>emptyList(),
+                  timeProvider);
+        }
       }
 
       checkState(!terminated, "Channel is terminated");
@@ -1291,15 +1305,7 @@
       builder.proxyDetector = nameResolverArgs.getProxyDetector();
       builder.defaultPort = nameResolverArgs.getDefaultPort();
       builder.userAgent = userAgent;
-      return
-          new ManagedChannelImpl(
-              builder,
-              transportFactory,
-              backoffPolicyProvider,
-              balancerRpcExecutorPool,
-              stopwatchSupplier,
-              Collections.<ClientInterceptor>emptyList(),
-              timeProvider);
+      return builder;
     }
 
     @Override
diff --git a/core/src/main/java/io/grpc/util/ForwardingLoadBalancerHelper.java b/core/src/main/java/io/grpc/util/ForwardingLoadBalancerHelper.java
index 95bf66c..85c5c7b 100644
--- a/core/src/main/java/io/grpc/util/ForwardingLoadBalancerHelper.java
+++ b/core/src/main/java/io/grpc/util/ForwardingLoadBalancerHelper.java
@@ -27,6 +27,7 @@
 import io.grpc.LoadBalancer.SubchannelPicker;
 import io.grpc.LoadBalancer;
 import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
 import io.grpc.NameResolver;
 import io.grpc.NameResolverRegistry;
 import io.grpc.SynchronizationContext;
@@ -69,6 +70,11 @@
   }
 
   @Override
+  public ManagedChannelBuilder<?> createResolvingOobChannelBuilder(String target) {
+    return delegate().createResolvingOobChannelBuilder(target);
+  }
+
+  @Override
   public ManagedChannel createResolvingOobChannel(String target) {
     return delegate().createResolvingOobChannel(target);
   }