aboutsummaryrefslogtreecommitdiff
path: root/android
diff options
context:
space:
mode:
authorEric Gribkoff <ericgribkoff@google.com>2018-06-07 08:39:42 -0700
committerGitHub <noreply@github.com>2018-06-07 08:39:42 -0700
commit3e4c692075d6e9d32e747057b901de6e7b859d1d (patch)
treeee7a611e5b7a258fd81d5fc5d46210dc5a0e9f9e /android
parent8f51c2731929ac104706f3f33f689c1cc2e4cd8d (diff)
downloadgrpc-grpc-java-3e4c692075d6e9d32e747057b901de6e7b859d1d.tar.gz
android: forward OkHttpChannelBuilder-specific methods to delegate (#4534)
Diffstat (limited to 'android')
-rw-r--r--android/src/main/java/io/grpc/android/AndroidChannelBuilder.java56
-rw-r--r--android/src/test/java/io/grpc/android/AndroidChannelBuilderTest.java133
2 files changed, 189 insertions, 0 deletions
diff --git a/android/src/main/java/io/grpc/android/AndroidChannelBuilder.java b/android/src/main/java/io/grpc/android/AndroidChannelBuilder.java
index 06e6ad8cc..3a824e23f 100644
--- a/android/src/main/java/io/grpc/android/AndroidChannelBuilder.java
+++ b/android/src/main/java/io/grpc/android/AndroidChannelBuilder.java
@@ -36,14 +36,20 @@ import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.MethodDescriptor;
import io.grpc.internal.GrpcUtil;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSocketFactory;
/**
* Builds a {@link ManagedChannel} that, when provided with a {@link Context}, will automatically
* monitor the Android device's network state to smoothly handle intermittent network failures.
*
+ * <p>Currently only compatible with gRPC's OkHttp transport, which must be available at runtime.
+ *
* <p>Requires the Android ACCESS_NETWORK_STATE permission.
*
* @since 1.12.0
@@ -96,6 +102,56 @@ public final class AndroidChannelBuilder extends ForwardingChannelBuilder<Androi
return this;
}
+ /** Set the delegate channel builder's transportExecutor. */
+ public AndroidChannelBuilder transportExecutor(@Nullable Executor transportExecutor) {
+ try {
+ OKHTTP_CHANNEL_BUILDER_CLASS
+ .getMethod("transportExecutor", Executor.class)
+ .invoke(delegateBuilder, transportExecutor);
+ return this;
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to invoke transportExecutor on delegate builder", e);
+ }
+ }
+
+ /** Set the delegate channel builder's hostnameVerifier. */
+ public AndroidChannelBuilder hostnameVerifier(@Nullable HostnameVerifier hostnameVerifier) {
+ try {
+ OKHTTP_CHANNEL_BUILDER_CLASS
+ .getMethod("hostnameVerifier", HostnameVerifier.class)
+ .invoke(delegateBuilder, hostnameVerifier);
+ return this;
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to invoke hostnameVerifier on delegate builder", e);
+ }
+ }
+
+ /** Set the delegate channel builder's sslSocketFactory. */
+ public AndroidChannelBuilder sslSocketFactory(SSLSocketFactory factory) {
+ try {
+ OKHTTP_CHANNEL_BUILDER_CLASS
+ .getMethod("sslSocketFactory", SSLSocketFactory.class)
+ .invoke(delegateBuilder, factory);
+ return this;
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to invoke sslSocketFactory on delegate builder", e);
+ }
+ }
+
+ /** Set the delegate channel builder's scheduledExecutorService. */
+ public AndroidChannelBuilder scheduledExecutorService(
+ ScheduledExecutorService scheduledExecutorService) {
+ try {
+ OKHTTP_CHANNEL_BUILDER_CLASS
+ .getMethod("scheduledExecutorService", ScheduledExecutorService.class)
+ .invoke(delegateBuilder, scheduledExecutorService);
+ return this;
+ } catch (Exception e) {
+ throw new RuntimeException(
+ "Failed to invoke scheduledExecutorService on delegate builder", e);
+ }
+ }
+
@Override
protected ManagedChannelBuilder<?> delegate() {
return delegateBuilder;
diff --git a/android/src/test/java/io/grpc/android/AndroidChannelBuilderTest.java b/android/src/test/java/io/grpc/android/AndroidChannelBuilderTest.java
index faf998f72..0477c34a0 100644
--- a/android/src/test/java/io/grpc/android/AndroidChannelBuilderTest.java
+++ b/android/src/test/java/io/grpc/android/AndroidChannelBuilderTest.java
@@ -31,8 +31,18 @@ import io.grpc.CallOptions;
import io.grpc.ClientCall;
import io.grpc.ManagedChannel;
import io.grpc.MethodDescriptor;
+import java.util.Collection;
import java.util.HashSet;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocketFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -87,6 +97,39 @@ public final class AndroidChannelBuilderTest {
}
@Test
+ public void transportExecutor() {
+ AndroidChannelBuilder.forTarget("target")
+ .transportExecutor(
+ new Executor() {
+ @Override
+ public void execute(Runnable r) {}
+ });
+ }
+
+ @Test
+ public void hostnameVerifier() {
+ AndroidChannelBuilder.forTarget("target")
+ .hostnameVerifier(
+ new HostnameVerifier() {
+ @Override
+ public boolean verify(String hostname, SSLSession session) {
+ return true;
+ }
+ });
+ }
+
+ @Test
+ public void sslSocketFactory() {
+ AndroidChannelBuilder.forTarget("target")
+ .sslSocketFactory((SSLSocketFactory) SSLSocketFactory.getDefault());
+ }
+
+ @Test
+ public void scheduledExecutorService() {
+ AndroidChannelBuilder.forTarget("target").scheduledExecutorService(new ScheduledExecutorImpl());
+ }
+
+ @Test
@Config(sdk = 23)
public void nullContextDoesNotThrow_api23() {
TestChannel delegateChannel = new TestChannel();
@@ -370,4 +413,94 @@ public final class AndroidChannelBuilderTest {
enterIdleCount++;
}
}
+
+ private static class ScheduledExecutorImpl implements ScheduledExecutorService {
+ @Override
+ public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ScheduledFuture<?> schedule(Runnable cmd, long delay, TimeUnit unit) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ScheduledFuture<?> scheduleAtFixedRate(
+ Runnable command, long initialDelay, long period, TimeUnit unit) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ScheduledFuture<?> scheduleWithFixedDelay(
+ Runnable command, long initialDelay, long delay, TimeUnit unit) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean awaitTermination(long timeout, TimeUnit unit) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <T> List<Future<T>> invokeAll(
+ Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <T> T invokeAny(Collection<? extends Callable<T>> tasks) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isShutdown() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isTerminated() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void shutdown() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public List<Runnable> shutdownNow() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <T> Future<T> submit(Callable<T> task) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Future<?> submit(Runnable task) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <T> Future<T> submit(Runnable task, T result) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void execute(Runnable command) {
+ throw new UnsupportedOperationException();
+ }
+ }
}