core: make StatsContextFactory setters protected (#2634)

These are only used in internal tests.  In production,
StatsContextFactory is loaded by the "Instrumentation" library and must
be one per process, thus we won't allow setting it on a per-channel or
per-server basis.
diff --git a/core/src/main/java/io/grpc/internal/AbstractManagedChannelImplBuilder.java b/core/src/main/java/io/grpc/internal/AbstractManagedChannelImplBuilder.java
index 6d5578b..cca6c55 100644
--- a/core/src/main/java/io/grpc/internal/AbstractManagedChannelImplBuilder.java
+++ b/core/src/main/java/io/grpc/internal/AbstractManagedChannelImplBuilder.java
@@ -44,7 +44,6 @@
 import io.grpc.ClientInterceptor;
 import io.grpc.CompressorRegistry;
 import io.grpc.DecompressorRegistry;
-import io.grpc.Internal;
 import io.grpc.LoadBalancer;
 import io.grpc.LoadBalancer2;
 import io.grpc.ManagedChannel;
@@ -259,11 +258,10 @@
   }
 
   /**
-   * Override the default stats implementation.  This is meant to be used in tests.
+   * Override the default stats implementation.
    */
   @VisibleForTesting
-  @Internal
-  public T statsContextFactory(StatsContextFactory statsFactory) {
+  protected T statsContextFactory(StatsContextFactory statsFactory) {
     this.statsFactory = statsFactory;
     return thisT();
   }
diff --git a/core/src/main/java/io/grpc/internal/AbstractServerImplBuilder.java b/core/src/main/java/io/grpc/internal/AbstractServerImplBuilder.java
index 78f2ca0..5cc4910 100644
--- a/core/src/main/java/io/grpc/internal/AbstractServerImplBuilder.java
+++ b/core/src/main/java/io/grpc/internal/AbstractServerImplBuilder.java
@@ -153,11 +153,10 @@
   }
 
   /**
-   * Override the default stats implementation.  This is meant to be used in tests.
+   * Override the default stats implementation.
    */
   @VisibleForTesting
-  @Internal
-  public T statsContextFactory(StatsContextFactory statsFactory) {
+  protected T statsContextFactory(StatsContextFactory statsFactory) {
     this.statsFactory = statsFactory;
     return thisT();
   }
diff --git a/core/src/test/java/io/grpc/internal/TestUtils.java b/core/src/test/java/io/grpc/internal/TestUtils.java
index 7e0f57a..1ca0660 100644
--- a/core/src/test/java/io/grpc/internal/TestUtils.java
+++ b/core/src/test/java/io/grpc/internal/TestUtils.java
@@ -36,6 +36,8 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import com.google.instrumentation.stats.StatsContextFactory;
+
 import io.grpc.CallOptions;
 import io.grpc.Metadata;
 import io.grpc.MethodDescriptor;
@@ -51,7 +53,7 @@
 /**
  * Common utility methods for tests.
  */
-final class TestUtils {
+public final class TestUtils {
 
   static class MockClientTransportInfo {
     /**
@@ -110,4 +112,23 @@
 
     return captor;
   }
+
+  /**
+   * Sets a custom {@link StatsContextFactory} for tests.
+   */
+  public static void setStatsContextFactory(
+      AbstractManagedChannelImplBuilder<?> builder, StatsContextFactory factory) {
+    builder.statsContextFactory(factory);
+  }
+
+  /**
+   * Sets a custom {@link StatsContextFactory} for tests.
+   */
+  public static void setStatsContextFactory(
+      AbstractServerImplBuilder<?> builder, StatsContextFactory factory) {
+    builder.statsContextFactory(factory);
+  }
+
+  private TestUtils() {
+  }
 }
diff --git a/interop-testing/build.gradle b/interop-testing/build.gradle
index 29e2835..5ba106f 100644
--- a/interop-testing/build.gradle
+++ b/interop-testing/build.gradle
@@ -16,6 +16,10 @@
             libraries.mockito,
             libraries.netty_tcnative,
             libraries.oauth_client
+
+    // Tests depend on base class defined by core module.
+    compile project(':grpc-core').sourceSets.test.output
+    testCompile project(':grpc-core').sourceSets.test.output
 }
 
 test {
diff --git a/interop-testing/src/main/java/io/grpc/testing/integration/AbstractInteropTest.java b/interop-testing/src/main/java/io/grpc/testing/integration/AbstractInteropTest.java
index bb84b5b..ab22616 100644
--- a/interop-testing/src/main/java/io/grpc/testing/integration/AbstractInteropTest.java
+++ b/interop-testing/src/main/java/io/grpc/testing/integration/AbstractInteropTest.java
@@ -152,7 +152,7 @@
     builder.addService(ServerInterceptors.intercept(
         new TestServiceImpl(testServiceExecutor),
         allInterceptors));
-    builder.statsContextFactory(serverStatsFactory);
+    io.grpc.internal.TestUtils.setStatsContextFactory(builder, serverStatsFactory);
     try {
       server = builder.build().start();
     } catch (IOException ex) {
diff --git a/interop-testing/src/test/java/io/grpc/testing/integration/AutoWindowSizingOnTest.java b/interop-testing/src/test/java/io/grpc/testing/integration/AutoWindowSizingOnTest.java
index 566e5e5..0247651 100644
--- a/interop-testing/src/test/java/io/grpc/testing/integration/AutoWindowSizingOnTest.java
+++ b/interop-testing/src/test/java/io/grpc/testing/integration/AutoWindowSizingOnTest.java
@@ -61,10 +61,10 @@
 
   @Override
   protected ManagedChannel createChannel() {
-    return NettyChannelBuilder.forAddress("localhost", getPort())
+    NettyChannelBuilder builder = NettyChannelBuilder.forAddress("localhost", getPort())
         .negotiationType(NegotiationType.PLAINTEXT)
-        .maxInboundMessageSize(AbstractInteropTest.MAX_MESSAGE_SIZE)
-        .statsContextFactory(getClientStatsFactory())
-        .build();
+        .maxInboundMessageSize(AbstractInteropTest.MAX_MESSAGE_SIZE);
+    io.grpc.internal.TestUtils.setStatsContextFactory(builder, getClientStatsFactory());
+    return builder.build();
   }
 }
diff --git a/interop-testing/src/test/java/io/grpc/testing/integration/Http2NettyLocalChannelTest.java b/interop-testing/src/test/java/io/grpc/testing/integration/Http2NettyLocalChannelTest.java
index 9c41c8f..423bd6d 100644
--- a/interop-testing/src/test/java/io/grpc/testing/integration/Http2NettyLocalChannelTest.java
+++ b/interop-testing/src/test/java/io/grpc/testing/integration/Http2NettyLocalChannelTest.java
@@ -69,13 +69,13 @@
 
   @Override
   protected ManagedChannel createChannel() {
-    return NettyChannelBuilder
+    NettyChannelBuilder builder = NettyChannelBuilder
         .forAddress(new LocalAddress("in-process-1"))
         .negotiationType(NegotiationType.PLAINTEXT)
         .channelType(LocalChannel.class)
         .flowControlWindow(65 * 1024)
-        .maxInboundMessageSize(AbstractInteropTest.MAX_MESSAGE_SIZE)
-        .statsContextFactory(getClientStatsFactory())
-        .build();
+        .maxInboundMessageSize(AbstractInteropTest.MAX_MESSAGE_SIZE);
+    io.grpc.internal.TestUtils.setStatsContextFactory(builder, getClientStatsFactory());
+    return builder.build();
   }
 }
diff --git a/interop-testing/src/test/java/io/grpc/testing/integration/Http2NettyTest.java b/interop-testing/src/test/java/io/grpc/testing/integration/Http2NettyTest.java
index 26146f7..33df33b 100644
--- a/interop-testing/src/test/java/io/grpc/testing/integration/Http2NettyTest.java
+++ b/interop-testing/src/test/java/io/grpc/testing/integration/Http2NettyTest.java
@@ -81,7 +81,7 @@
   @Override
   protected ManagedChannel createChannel() {
     try {
-      return NettyChannelBuilder
+      NettyChannelBuilder builder = NettyChannelBuilder
           .forAddress(TestUtils.testServerAddress(getPort()))
           .flowControlWindow(65 * 1024)
           .maxInboundMessageSize(AbstractInteropTest.MAX_MESSAGE_SIZE)
@@ -91,9 +91,9 @@
               .trustManager(TestUtils.loadX509Cert("ca.pem"))
               .ciphers(TestUtils.preferredTestCiphers(), SupportedCipherSuiteFilter.INSTANCE)
               .sslProvider(SslProvider.OPENSSL)
-              .build())
-          .statsContextFactory(getClientStatsFactory())
-          .build();
+              .build());
+      io.grpc.internal.TestUtils.setStatsContextFactory(builder, getClientStatsFactory());
+      return builder.build();
     } catch (Exception ex) {
       throw new RuntimeException(ex);
     }
diff --git a/interop-testing/src/test/java/io/grpc/testing/integration/Http2OkHttpTest.java b/interop-testing/src/test/java/io/grpc/testing/integration/Http2OkHttpTest.java
index 4284399..d5ed96c 100644
--- a/interop-testing/src/test/java/io/grpc/testing/integration/Http2OkHttpTest.java
+++ b/interop-testing/src/test/java/io/grpc/testing/integration/Http2OkHttpTest.java
@@ -108,9 +108,9 @@
             .cipherSuites(TestUtils.preferredTestCiphers().toArray(new String[0]))
             .tlsVersions(ConnectionSpec.MODERN_TLS.tlsVersions().toArray(new TlsVersion[0]))
             .build())
-        .statsContextFactory(getClientStatsFactory())
         .overrideAuthority(GrpcUtil.authorityFromHostAndPort(
             TestUtils.TEST_SERVER_HOST, getPort()));
+    io.grpc.internal.TestUtils.setStatsContextFactory(builder, getClientStatsFactory());
     try {
       builder.sslSocketFactory(TestUtils.newSslSocketFactoryForCa(Platform.get().getProvider(),
               TestUtils.loadCert("ca.pem")));
diff --git a/interop-testing/src/test/java/io/grpc/testing/integration/TransportCompressionTest.java b/interop-testing/src/test/java/io/grpc/testing/integration/TransportCompressionTest.java
index ec8df01..cf62b67 100644
--- a/interop-testing/src/test/java/io/grpc/testing/integration/TransportCompressionTest.java
+++ b/interop-testing/src/test/java/io/grpc/testing/integration/TransportCompressionTest.java
@@ -148,11 +148,10 @@
 
   @Override
   protected ManagedChannel createChannel() {
-    return NettyChannelBuilder.forAddress("localhost", getPort())
+    NettyChannelBuilder builder = NettyChannelBuilder.forAddress("localhost", getPort())
         .maxInboundMessageSize(AbstractInteropTest.MAX_MESSAGE_SIZE)
         .decompressorRegistry(decompressors)
         .compressorRegistry(compressors)
-        .statsContextFactory(getClientStatsFactory())
         .intercept(new ClientInterceptor() {
           @Override
           public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
@@ -190,8 +189,9 @@
             };
           }
         })
-        .usePlaintext(true)
-        .build();
+        .usePlaintext(true);
+    io.grpc.internal.TestUtils.setStatsContextFactory(builder, getClientStatsFactory());
+    return builder.build();
   }
 
   /**