diff --git a/binder/src/main/java/io/grpc/binder/AndroidComponentAddress.java b/binder/src/main/java/io/grpc/binder/AndroidComponentAddress.java index abcabea4f2b..cb4f7f794cf 100644 --- a/binder/src/main/java/io/grpc/binder/AndroidComponentAddress.java +++ b/binder/src/main/java/io/grpc/binder/AndroidComponentAddress.java @@ -121,9 +121,17 @@ public Intent asBindIntent() { /** * Returns this address as an "android-app://" uri. + * + *

See {@link Intent#URI_ANDROID_APP_SCHEME} for details. */ public String asAndroidAppUri() { - return bindIntent.toUri(URI_ANDROID_APP_SCHEME); + Intent intentForUri = bindIntent; + if (intentForUri.getPackage() == null) { + // URI_ANDROID_APP_SCHEME requires an "explicit package name" which isn't set by any of our + // factory methods. Oddly, our explicit ComponentName is not enough. + intentForUri = intentForUri.cloneFilter().setPackage(getComponent().getPackageName()); + } + return intentForUri.toUri(URI_ANDROID_APP_SCHEME); } @Override diff --git a/binder/src/test/java/io/grpc/binder/AndroidComponentAddressTest.java b/binder/src/test/java/io/grpc/binder/AndroidComponentAddressTest.java index 5824c953d18..8c7bc83d214 100644 --- a/binder/src/test/java/io/grpc/binder/AndroidComponentAddressTest.java +++ b/binder/src/test/java/io/grpc/binder/AndroidComponentAddressTest.java @@ -16,6 +16,7 @@ package io.grpc.binder; +import static android.content.Intent.URI_ANDROID_APP_SCHEME; import static com.google.common.truth.Truth.assertThat; import android.content.ComponentName; @@ -24,6 +25,7 @@ import android.net.Uri; import androidx.test.core.app.ApplicationProvider; import com.google.common.testing.EqualsTester; +import java.net.URISyntaxException; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; @@ -61,6 +63,30 @@ public void testAsBindIntent() { assertThat(addr.asBindIntent().filterEquals(bindIntent)).isTrue(); } + @Test + @Config(sdk = 30) + public void testAsAndroidAppUriSdk30() throws URISyntaxException { + AndroidComponentAddress addr = + AndroidComponentAddress.forRemoteComponent("com.foo", "com.foo.Service"); + AndroidComponentAddress addrClone = + AndroidComponentAddress.forBindIntent( + Intent.parseUri(addr.asAndroidAppUri(), URI_ANDROID_APP_SCHEME)); + assertThat(addr).isEqualTo(addrClone); + } + + @Test + @Config(sdk = 29) + public void testAsAndroidAppUriSdk29() throws URISyntaxException { + AndroidComponentAddress addr = + AndroidComponentAddress.forRemoteComponent("com.foo", "com.foo.Service"); + AndroidComponentAddress addrClone = + AndroidComponentAddress.forBindIntent( + Intent.parseUri(addr.asAndroidAppUri(), URI_ANDROID_APP_SCHEME)); + // Can't test for equality because URI_ANDROID_APP_SCHEME adds a (redundant) package filter. + assertThat(addr.getComponent()).isEqualTo(addrClone.getComponent()); + assertThat(addr.getAuthority()).isEqualTo(addrClone.getAuthority()); + } + @Test public void testEquality() { new EqualsTester()