mirror of https://github.com/grpc/grpc-java.git
android: add grpc-android into main build (#6793)
Add grpc-android into main build. grpc-android will be built if Gradle option skipAndroid is false. This change also migrates deprecated Robolectric methods to androidx.test methods.
This commit is contained in:
parent
a57f1a9636
commit
5ba663bcf6
|
@ -1,27 +1,11 @@
|
|||
apply plugin: 'com.android.library'
|
||||
plugins {
|
||||
id "maven-publish"
|
||||
|
||||
group = "io.grpc"
|
||||
version = "1.29.0-SNAPSHOT" // CURRENT_GRPC_VERSION
|
||||
description = 'gRPC: Android'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
maven { url "https://plugins.gradle.org/m2/" }
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.3.0'
|
||||
classpath "net.ltgt.gradle:gradle-errorprone-plugin:0.8.1"
|
||||
classpath "digital.wup:android-maven-publish:3.6.2"
|
||||
}
|
||||
id "com.android.library"
|
||||
id "digital.wup.android-maven-publish"
|
||||
}
|
||||
|
||||
apply plugin: "maven-publish"
|
||||
apply plugin: "net.ltgt.errorprone"
|
||||
apply plugin: "digital.wup.android-maven-publish"
|
||||
apply plugin: "signing"
|
||||
description = 'gRPC: Android'
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
|
@ -39,20 +23,16 @@ android {
|
|||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
errorprone 'com.google.errorprone:error_prone_core:2.3.4'
|
||||
errorproneJavac 'com.google.errorprone:javac:9+181-r4173-1'
|
||||
implementation project(':grpc-core')
|
||||
|
||||
implementation 'io.grpc:grpc-core:1.29.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
|
||||
testImplementation 'io.grpc:grpc-okhttp:1.29.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
testImplementation 'junit:junit:4.12'
|
||||
testImplementation 'org.robolectric:robolectric:4.3.1'
|
||||
testImplementation 'com.google.truth:truth:1.0.1'
|
||||
testImplementation project('::grpc-okhttp')
|
||||
testImplementation libraries.androidx_test
|
||||
testImplementation libraries.junit
|
||||
testImplementation libraries.robolectric
|
||||
testImplementation libraries.truth
|
||||
}
|
||||
|
||||
task javadocs(type: Javadoc) {
|
||||
|
@ -83,81 +63,11 @@ task sourcesJar(type: Jar) {
|
|||
|
||||
publishing {
|
||||
publications {
|
||||
maven(MavenPublication) {
|
||||
maven {
|
||||
from components.android
|
||||
|
||||
artifact javadocJar
|
||||
artifact sourcesJar
|
||||
|
||||
pom {
|
||||
name = project.group + ":" + project.name
|
||||
url = 'https://github.com/grpc/grpc-java'
|
||||
afterEvaluate {
|
||||
// description is not available until evaluated.
|
||||
description = project.description
|
||||
}
|
||||
|
||||
scm {
|
||||
connection = 'scm:git:https://github.com/grpc/grpc-java.git'
|
||||
developerConnection = 'scm:git:git@github.com:grpc/grpc-java.git'
|
||||
url = 'https://github.com/grpc/grpc-java'
|
||||
}
|
||||
|
||||
licenses {
|
||||
license {
|
||||
name = 'Apache 2.0'
|
||||
url = 'https://opensource.org/licenses/Apache-2.0'
|
||||
}
|
||||
}
|
||||
|
||||
developers {
|
||||
developer {
|
||||
id = "grpc.io"
|
||||
name = "gRPC Contributors"
|
||||
email = "grpc-io@googlegroups.com"
|
||||
url = "https://grpc.io/"
|
||||
organization = "gRPC Authors"
|
||||
organizationUrl = "https://www.google.com"
|
||||
}
|
||||
}
|
||||
|
||||
withXml {
|
||||
asNode().dependencies.'*'.findAll() { dep ->
|
||||
dep.artifactId.text() in ['grpc-api', 'grpc-core']
|
||||
}.each() { core ->
|
||||
core.version*.value = "[" + core.version.text() + "]"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
maven {
|
||||
if (rootProject.hasProperty('repositoryDir')) {
|
||||
url = new File(rootProject.repositoryDir).toURI()
|
||||
} else {
|
||||
String stagingUrl
|
||||
if (rootProject.hasProperty('repositoryId')) {
|
||||
stagingUrl = 'https://oss.sonatype.org/service/local/staging/deployByRepositoryId/' +
|
||||
rootProject.repositoryId
|
||||
} else {
|
||||
stagingUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
|
||||
}
|
||||
credentials {
|
||||
if (rootProject.hasProperty('ossrhUsername') && rootProject.hasProperty('ossrhPassword')) {
|
||||
username = rootProject.ossrhUsername
|
||||
password = rootProject.ossrhPassword
|
||||
}
|
||||
}
|
||||
def releaseUrl = stagingUrl
|
||||
def snapshotUrl = 'https://oss.sonatype.org/content/repositories/snapshots/'
|
||||
url = version.endsWith('SNAPSHOT') ? snapshotUrl : releaseUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signing {
|
||||
required false
|
||||
sign publishing.publications.maven
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
rootProject.name = 'grpc-android'
|
|
@ -28,6 +28,7 @@ import android.content.Intent;
|
|||
import android.net.ConnectivityManager;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkInfo;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import io.grpc.CallOptions;
|
||||
import io.grpc.ClientCall;
|
||||
import io.grpc.ManagedChannel;
|
||||
|
@ -39,7 +40,6 @@ import org.junit.Before;
|
|||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
@ -54,24 +54,32 @@ import org.robolectric.shadows.ShadowNetworkInfo;
|
|||
public final class AndroidChannelBuilderTest {
|
||||
private final NetworkInfo WIFI_CONNECTED =
|
||||
ShadowNetworkInfo.newInstance(
|
||||
NetworkInfo.DetailedState.CONNECTED, ConnectivityManager.TYPE_WIFI, 0, true, true);
|
||||
NetworkInfo.DetailedState.CONNECTED,
|
||||
ConnectivityManager.TYPE_WIFI,
|
||||
0,
|
||||
true,
|
||||
NetworkInfo.State.CONNECTED);
|
||||
private final NetworkInfo WIFI_DISCONNECTED =
|
||||
ShadowNetworkInfo.newInstance(
|
||||
NetworkInfo.DetailedState.DISCONNECTED, ConnectivityManager.TYPE_WIFI, 0, true, false);
|
||||
NetworkInfo.DetailedState.DISCONNECTED,
|
||||
ConnectivityManager.TYPE_WIFI,
|
||||
0,
|
||||
true,
|
||||
NetworkInfo.State.DISCONNECTED);
|
||||
private final NetworkInfo MOBILE_CONNECTED =
|
||||
ShadowNetworkInfo.newInstance(
|
||||
NetworkInfo.DetailedState.CONNECTED,
|
||||
ConnectivityManager.TYPE_MOBILE,
|
||||
ConnectivityManager.TYPE_MOBILE_MMS,
|
||||
true,
|
||||
true);
|
||||
NetworkInfo.State.CONNECTED);
|
||||
private final NetworkInfo MOBILE_DISCONNECTED =
|
||||
ShadowNetworkInfo.newInstance(
|
||||
NetworkInfo.DetailedState.DISCONNECTED,
|
||||
ConnectivityManager.TYPE_MOBILE,
|
||||
ConnectivityManager.TYPE_MOBILE_MMS,
|
||||
true,
|
||||
false);
|
||||
NetworkInfo.State.DISCONNECTED);
|
||||
|
||||
private ConnectivityManager connectivityManager;
|
||||
|
||||
|
@ -79,7 +87,9 @@ public final class AndroidChannelBuilderTest {
|
|||
public void setUp() {
|
||||
connectivityManager =
|
||||
(ConnectivityManager)
|
||||
RuntimeEnvironment.application.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
ApplicationProvider
|
||||
.getApplicationContext()
|
||||
.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -103,8 +113,9 @@ public final class AndroidChannelBuilderTest {
|
|||
|
||||
// Network change and shutdown should be no-op for the channel without an Android Context
|
||||
shadowOf(connectivityManager).setActiveNetworkInfo(WIFI_CONNECTED);
|
||||
RuntimeEnvironment.application.sendBroadcast(
|
||||
new Intent(ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
ApplicationProvider
|
||||
.getApplicationContext()
|
||||
.sendBroadcast(new Intent(ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
androidChannel.shutdown();
|
||||
|
||||
assertThat(delegateChannel.resetCount).isEqualTo(0);
|
||||
|
@ -131,48 +142,55 @@ public final class AndroidChannelBuilderTest {
|
|||
TestChannel delegateChannel = new TestChannel();
|
||||
ManagedChannel androidChannel =
|
||||
new AndroidChannelBuilder.AndroidChannel(
|
||||
delegateChannel, RuntimeEnvironment.application.getApplicationContext());
|
||||
delegateChannel, ApplicationProvider.getApplicationContext());
|
||||
assertThat(delegateChannel.resetCount).isEqualTo(0);
|
||||
|
||||
// On API levels < 24, the broadcast receiver will invoke resetConnectBackoff() on the first
|
||||
// connectivity action broadcast regardless of previous connection status
|
||||
shadowOf(connectivityManager).setActiveNetworkInfo(WIFI_CONNECTED);
|
||||
RuntimeEnvironment.application.sendBroadcast(
|
||||
new Intent(ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
ApplicationProvider
|
||||
.getApplicationContext()
|
||||
.sendBroadcast(new Intent(ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
assertThat(delegateChannel.resetCount).isEqualTo(1);
|
||||
|
||||
// The broadcast receiver may fire when the active network status has not actually changed
|
||||
RuntimeEnvironment.application.sendBroadcast(
|
||||
new Intent(ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
ApplicationProvider
|
||||
.getApplicationContext()
|
||||
.sendBroadcast(new Intent(ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
assertThat(delegateChannel.resetCount).isEqualTo(1);
|
||||
|
||||
// Drop the connection
|
||||
shadowOf(connectivityManager).setActiveNetworkInfo(null);
|
||||
RuntimeEnvironment.application.sendBroadcast(
|
||||
new Intent(ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
ApplicationProvider
|
||||
.getApplicationContext()
|
||||
.sendBroadcast(new Intent(ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
assertThat(delegateChannel.resetCount).isEqualTo(1);
|
||||
|
||||
// Notify that a new but not connected network is available
|
||||
shadowOf(connectivityManager).setActiveNetworkInfo(MOBILE_DISCONNECTED);
|
||||
RuntimeEnvironment.application.sendBroadcast(
|
||||
new Intent(ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
ApplicationProvider
|
||||
.getApplicationContext()
|
||||
.sendBroadcast(new Intent(ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
assertThat(delegateChannel.resetCount).isEqualTo(1);
|
||||
|
||||
// Establish a connection
|
||||
shadowOf(connectivityManager).setActiveNetworkInfo(MOBILE_CONNECTED);
|
||||
RuntimeEnvironment.application.sendBroadcast(
|
||||
new Intent(ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
ApplicationProvider
|
||||
.getApplicationContext()
|
||||
.sendBroadcast(new Intent(ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
assertThat(delegateChannel.resetCount).isEqualTo(2);
|
||||
|
||||
// Disconnect, then shutdown the channel and verify that the broadcast receiver has been
|
||||
// unregistered
|
||||
shadowOf(connectivityManager).setActiveNetworkInfo(null);
|
||||
RuntimeEnvironment.application.sendBroadcast(
|
||||
new Intent(ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
ApplicationProvider
|
||||
.getApplicationContext()
|
||||
.sendBroadcast(new Intent(ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
androidChannel.shutdown();
|
||||
shadowOf(connectivityManager).setActiveNetworkInfo(MOBILE_CONNECTED);
|
||||
RuntimeEnvironment.application.sendBroadcast(
|
||||
new Intent(ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
ApplicationProvider
|
||||
.getApplicationContext()
|
||||
.sendBroadcast(new Intent(ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
|
||||
assertThat(delegateChannel.resetCount).isEqualTo(2);
|
||||
// enterIdle is not called on API levels < 24
|
||||
|
@ -186,7 +204,7 @@ public final class AndroidChannelBuilderTest {
|
|||
TestChannel delegateChannel = new TestChannel();
|
||||
ManagedChannel androidChannel =
|
||||
new AndroidChannelBuilder.AndroidChannel(
|
||||
delegateChannel, RuntimeEnvironment.application.getApplicationContext());
|
||||
delegateChannel, ApplicationProvider.getApplicationContext());
|
||||
assertThat(delegateChannel.resetCount).isEqualTo(0);
|
||||
assertThat(delegateChannel.enterIdleCount).isEqualTo(0);
|
||||
|
||||
|
@ -227,7 +245,7 @@ public final class AndroidChannelBuilderTest {
|
|||
TestChannel delegateChannel = new TestChannel();
|
||||
ManagedChannel androidChannel =
|
||||
new AndroidChannelBuilder.AndroidChannel(
|
||||
delegateChannel, RuntimeEnvironment.application.getApplicationContext());
|
||||
delegateChannel, ApplicationProvider.getApplicationContext());
|
||||
|
||||
// The first onAvailable() may just signal that the device was connected when the callback is
|
||||
// registered, rather than indicating a changed network, so we do not enter idle.
|
||||
|
@ -248,15 +266,17 @@ public final class AndroidChannelBuilderTest {
|
|||
TestChannel delegateChannel = new TestChannel();
|
||||
ManagedChannel androidChannel =
|
||||
new AndroidChannelBuilder.AndroidChannel(
|
||||
delegateChannel, RuntimeEnvironment.application.getApplicationContext());
|
||||
delegateChannel, ApplicationProvider.getApplicationContext());
|
||||
|
||||
shadowOf(connectivityManager).setActiveNetworkInfo(null);
|
||||
RuntimeEnvironment.application.sendBroadcast(
|
||||
new Intent(ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
ApplicationProvider
|
||||
.getApplicationContext()
|
||||
.sendBroadcast(new Intent(ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
androidChannel.shutdownNow();
|
||||
shadowOf(connectivityManager).setActiveNetworkInfo(WIFI_CONNECTED);
|
||||
RuntimeEnvironment.application.sendBroadcast(
|
||||
new Intent(ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
ApplicationProvider
|
||||
.getApplicationContext()
|
||||
.sendBroadcast(new Intent(ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
|
||||
assertThat(delegateChannel.resetCount).isEqualTo(0);
|
||||
}
|
||||
|
@ -268,7 +288,7 @@ public final class AndroidChannelBuilderTest {
|
|||
TestChannel delegateChannel = new TestChannel();
|
||||
ManagedChannel androidChannel =
|
||||
new AndroidChannelBuilder.AndroidChannel(
|
||||
delegateChannel, RuntimeEnvironment.application.getApplicationContext());
|
||||
delegateChannel, ApplicationProvider.getApplicationContext());
|
||||
|
||||
androidChannel.shutdownNow();
|
||||
shadowOf(connectivityManager).setActiveNetworkInfo(WIFI_CONNECTED);
|
||||
|
@ -318,6 +338,7 @@ public final class AndroidChannelBuilderTest {
|
|||
}
|
||||
|
||||
@Implementation(minSdk = N)
|
||||
@Override
|
||||
protected void registerDefaultNetworkCallback(
|
||||
ConnectivityManager.NetworkCallback networkCallback) {
|
||||
defaultNetworkCallbacks.add(networkCallback);
|
||||
|
|
|
@ -157,6 +157,7 @@ subprojects {
|
|||
mockito: 'org.mockito:mockito-core:2.28.2',
|
||||
truth: 'com.google.truth:truth:1.0.1',
|
||||
guava_testlib: "com.google.guava:guava-testlib:${guavaVersion}",
|
||||
androidx_test: "androidx.test:core:1.2.0",
|
||||
robolectric: "org.robolectric:robolectric:4.3.1",
|
||||
|
||||
// Benchmark dependencies
|
||||
|
|
|
@ -16,7 +16,6 @@ echo y | ${ANDROID_HOME}/tools/bin/sdkmanager "build-tools;28.0.3"
|
|||
LOCAL_MVN_TEMP=$(mktemp -d)
|
||||
pushd "$GRPC_JAVA_DIR/android"
|
||||
../gradlew publish \
|
||||
--include-build "$GRPC_JAVA_DIR" \
|
||||
-Dorg.gradle.parallel=false \
|
||||
-PskipCodegen=true \
|
||||
-PrepositoryDir="$LOCAL_MVN_TEMP"
|
||||
|
|
|
@ -86,4 +86,6 @@ if (settings.hasProperty('skipAndroid') && skipAndroid.toBoolean()) {
|
|||
println '*** Android SDK is required. To avoid building Android projects, set -PskipAndroid=true'
|
||||
include ":grpc-cronet"
|
||||
project(':grpc-cronet').projectDir = "$rootDir/cronet" as File
|
||||
include ":grpc-android"
|
||||
project(':grpc-android').projectDir = "$rootDir/android" as File
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue