android: Use InternalManagedChannelProvider instead of reflection

This fixes up cda0e9d to be compatible with Proguard without
configuration. Since the methods are now accessed directly there is no
need for manual -keep configuration.
This commit is contained in:
Eric Anderson 2022-03-31 11:11:57 -07:00
parent 86e3362298
commit 40c929e39f
2 changed files with 22 additions and 21 deletions

View File

@ -33,8 +33,10 @@ import io.grpc.ClientCall;
import io.grpc.ConnectivityState; import io.grpc.ConnectivityState;
import io.grpc.ExperimentalApi; import io.grpc.ExperimentalApi;
import io.grpc.ForwardingChannelBuilder; import io.grpc.ForwardingChannelBuilder;
import io.grpc.InternalManagedChannelProvider;
import io.grpc.ManagedChannel; import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder; import io.grpc.ManagedChannelBuilder;
import io.grpc.ManagedChannelProvider;
import io.grpc.MethodDescriptor; import io.grpc.MethodDescriptor;
import io.grpc.internal.GrpcUtil; import io.grpc.internal.GrpcUtil;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -55,30 +57,32 @@ public final class AndroidChannelBuilder extends ForwardingChannelBuilder<Androi
private static final String LOG_TAG = "AndroidChannelBuilder"; private static final String LOG_TAG = "AndroidChannelBuilder";
@Nullable private static final Object OKHTTP_CHANNEL_PROVIDER = findOkHttp(); @Nullable private static final ManagedChannelProvider OKHTTP_CHANNEL_PROVIDER = findOkHttp();
private static Object findOkHttp() { private static ManagedChannelProvider findOkHttp() {
Class<?> klass; Class<?> klassRaw;
try { try {
klass = Class.forName("io.grpc.okhttp.OkHttpChannelProvider"); klassRaw = Class.forName("io.grpc.okhttp.OkHttpChannelProvider");
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
Log.w(LOG_TAG, "Failed to find OkHttpChannelProvider", e); Log.w(LOG_TAG, "Failed to find OkHttpChannelProvider", e);
return null; return null;
} }
Object provider; Class<? extends ManagedChannelProvider> klass;
try {
klass = klassRaw.asSubclass(ManagedChannelProvider.class);
} catch (ClassCastException e) {
Log.w(LOG_TAG, "Couldn't cast OkHttpChannelProvider to ManagedChannelProvider", e);
return null;
}
ManagedChannelProvider provider;
try { try {
provider = klass.getConstructor().newInstance(); provider = klass.getConstructor().newInstance();
} catch (Exception e) { } catch (Exception e) {
Log.w(LOG_TAG, "Failed to construct OkHttpChannelProvider", e); Log.w(LOG_TAG, "Failed to construct OkHttpChannelProvider", e);
return null; return null;
} }
try { if (!InternalManagedChannelProvider.isAvailable(provider)) {
if (!(Boolean) klass.getMethod("isAvailable").invoke(provider)) { Log.w(LOG_TAG, "OkHttpChannelProvider.isAvailable() returned false");
Log.w(LOG_TAG, "OkHttpChannelProvider.isAvailable() returned false");
return null;
}
} catch (Exception e) {
Log.w(LOG_TAG, "Failed to check OkHttpChannelProvider.isAvailable()", e);
return null; return null;
} }
return provider; return provider;
@ -135,15 +139,8 @@ public final class AndroidChannelBuilder extends ForwardingChannelBuilder<Androi
if (OKHTTP_CHANNEL_PROVIDER == null) { if (OKHTTP_CHANNEL_PROVIDER == null) {
throw new UnsupportedOperationException("Unable to load OkHttpChannelProvider"); throw new UnsupportedOperationException("Unable to load OkHttpChannelProvider");
} }
try { delegateBuilder =
delegateBuilder = InternalManagedChannelProvider.builderForTarget(OKHTTP_CHANNEL_PROVIDER, target);
(ManagedChannelBuilder)
OKHTTP_CHANNEL_PROVIDER.getClass()
.getMethod("builderForTarget", String.class)
.invoke(OKHTTP_CHANNEL_PROVIDER, target);
} catch (Exception e) {
throw new RuntimeException("Failed to create ManagedChannelBuilder", e);
}
} }
private AndroidChannelBuilder(ManagedChannelBuilder<?> delegateBuilder) { private AndroidChannelBuilder(ManagedChannelBuilder<?> delegateBuilder) {

View File

@ -25,6 +25,10 @@ public final class InternalManagedChannelProvider {
private InternalManagedChannelProvider() { private InternalManagedChannelProvider() {
} }
public static boolean isAvailable(ManagedChannelProvider provider) {
return provider.isAvailable();
}
public static ManagedChannelBuilder<?> builderForAddress(ManagedChannelProvider provider, public static ManagedChannelBuilder<?> builderForAddress(ManagedChannelProvider provider,
String name, int port) { String name, int port) {
return provider.builderForAddress(name, port); return provider.builderForAddress(name, port);