diff --git a/CHANGELOG.md b/CHANGELOG.md index 8629b179bff..5e4e91ba9ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### PaymentSheet * [Added][12011](https://github.com/stripe/stripe-android/pull/12011) Builder APIs for PaymentSheet appearance customization (Colors, Shapes, Typography, PrimaryButtonColors, and embedded row styles) * [Added] opensCardScannerAutomatically configuration is now available. +* [CHANGED][12036](https://github.com/stripe/stripe-android/pull/12036) Updates the google places SDK from 3.5.0 to 5.0.0. ### Payments * [Added][12014](https://github.com/stripe/stripe-android/pull/12014) `ConfirmationToken.PaymentMethodPreview` now includes structured `Card` field with detailed card information (brand, country, expiry, funding, last4, etc.) diff --git a/dependencies.gradle b/dependencies.gradle index 8a982bacdd9..b69c82591bb 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -59,7 +59,7 @@ ext.versions = [ paparazzi : '2.0.0-alpha01', poko : '0.18.2', payButtonCompose : '0.1.3', - places : '3.5.0', + places : '5.0.0', playServicesCoroutines : '1.10.1', playServicesTfLite : '16.4.0', playServicesWallet : '19.4.0', diff --git a/payments-ui-core/src/main/AndroidManifest.xml b/payments-ui-core/src/main/AndroidManifest.xml index e1000761579..e83f5a6009f 100644 --- a/payments-ui-core/src/main/AndroidManifest.xml +++ b/payments-ui-core/src/main/AndroidManifest.xml @@ -1,4 +1,5 @@ - + + diff --git a/payments-ui-core/src/main/java/com/stripe/android/ui/core/elements/autocomplete/PlacesClientProxy.kt b/payments-ui-core/src/main/java/com/stripe/android/ui/core/elements/autocomplete/PlacesClientProxy.kt index 91bf7786469..4396877bd87 100644 --- a/payments-ui-core/src/main/java/com/stripe/android/ui/core/elements/autocomplete/PlacesClientProxy.kt +++ b/payments-ui-core/src/main/java/com/stripe/android/ui/core/elements/autocomplete/PlacesClientProxy.kt @@ -2,12 +2,13 @@ package com.stripe.android.ui.core.elements.autocomplete import android.content.Context import android.graphics.Typeface +import android.os.Build import android.text.style.StyleSpan import androidx.annotation.RestrictTo import androidx.annotation.VisibleForTesting import com.google.android.libraries.places.api.Places import com.google.android.libraries.places.api.model.AutocompleteSessionToken -import com.google.android.libraries.places.api.model.TypeFilter +import com.google.android.libraries.places.api.model.PlaceTypes import com.google.android.libraries.places.api.net.FetchPlaceRequest import com.google.android.libraries.places.api.net.FindAutocompletePredictionsRequest import com.google.android.libraries.places.api.net.PlacesClient @@ -50,7 +51,7 @@ interface PlacesClientProxy { initializer: () -> Unit = { Places.initialize(context, googlePlacesApiKey) }, errorReporter: ErrorReporter ): PlacesClientProxy { - return if (isPlacesAvailable()) { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && isPlacesAvailable()) { override ?: run { initializer() DefaultPlacesClientProxy( @@ -102,8 +103,8 @@ internal class DefaultPlacesClientProxy( .builder() .setSessionToken(token) .setQuery(query) - .setCountry(country) - .setTypeFilter(TypeFilter.ADDRESS) + .setCountries(listOf(country)) + .setTypesFilter(listOf(PlaceTypes.ADDRESS)) .build() ).await() errorReporter.report(ErrorReporter.SuccessEvent.PLACES_FIND_AUTOCOMPLETE_SUCCESS) diff --git a/payments-ui-core/src/test/java/com/stripe/android/ui/core/elements/autocomplete/PlacesClientProxyTest.kt b/payments-ui-core/src/test/java/com/stripe/android/ui/core/elements/autocomplete/PlacesClientProxyTest.kt index 0048ea4337a..82b8e2c869b 100644 --- a/payments-ui-core/src/test/java/com/stripe/android/ui/core/elements/autocomplete/PlacesClientProxyTest.kt +++ b/payments-ui-core/src/test/java/com/stripe/android/ui/core/elements/autocomplete/PlacesClientProxyTest.kt @@ -1,5 +1,7 @@ package com.stripe.android.ui.core.elements.autocomplete +import android.os.Build +import com.google.android.gms.maps.model.LatLng import com.google.android.gms.tasks.Task import com.google.android.gms.tasks.Tasks import com.google.android.libraries.places.api.model.AutocompletePrediction @@ -21,6 +23,7 @@ import com.google.android.libraries.places.api.net.SearchByTextRequest import com.google.android.libraries.places.api.net.SearchByTextResponse import com.google.android.libraries.places.api.net.SearchNearbyRequest import com.google.android.libraries.places.api.net.SearchNearbyResponse +import com.google.android.libraries.places.internal.zzmu import com.google.common.truth.Truth.assertThat import com.stripe.android.testing.CoroutineTestRule import com.stripe.android.testing.FakeErrorReporter @@ -34,6 +37,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.mock import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config @RunWith(RobolectricTestRunner::class) class PlacesClientProxyTest { @@ -59,6 +63,25 @@ class PlacesClientProxyTest { assertThat(client).isInstanceOf() } + @Test + @Config(sdk = [Build.VERSION_CODES.M]) + fun `create returns unsupported client when run on old devices`() { + val client = PlacesClientProxy.create( + context = mock(), + googlePlacesApiKey = "abc123", + isPlacesAvailable = object : IsPlacesAvailable { + override fun invoke(): Boolean { + throw IllegalStateException("Shouldn't be called.") + } + }, + clientFactory = { mock() }, + initializer = { /* no-op */ }, + errorReporter = FakeErrorReporter(), + ) + + assertThat(client).isInstanceOf() + } + @Test fun `create returns unsupported client when google places not available`() { val client = PlacesClientProxy.create( @@ -229,17 +252,75 @@ class PlacesClientProxyTest { throw AssertionError("Not expected") } + override fun zza( + p0: FindAutocompletePredictionsRequest?, + p1: zzmu? + ): Task<*>? { + throw AssertionError("Not expected") + } + override fun zzb( - p0: FetchPlaceRequest, - p1: Int - ): Task<*> { + p0: FetchPhotoRequest?, + p1: zzmu? + ): Task<*>? { + throw AssertionError("Not expected") + } + + override fun zzc( + p0: FetchResolvedPhotoUriRequest?, + p1: zzmu? + ): Task<*>? { throw AssertionError("Not expected") } override fun zzd( - p0: FindAutocompletePredictionsRequest, - p1: Int - ): Task<*> { + p0: FetchPlaceRequest?, + p1: zzmu? + ): Task<*>? { + throw AssertionError("Not expected") + } + + override fun zze(p0: LatLng): Task<*> { + throw AssertionError("Not expected") + } + + override fun zzf( + p0: FindCurrentPlaceRequest?, + p1: zzmu? + ): Task<*>? { + throw AssertionError("Not expected") + } + + override fun zzh( + p0: IsOpenRequest?, + p1: zzmu? + ): Task<*>? { + throw AssertionError("Not expected") + } + + override fun zzi( + p0: SearchByTextRequest?, + p1: zzmu? + ): Task<*>? { + throw AssertionError("Not expected") + } + + override fun zzj( + p0: SearchNearbyRequest?, + p1: zzmu? + ): Task<*>? { + throw AssertionError("Not expected") + } + + override fun zzk() { + throw AssertionError("Not expected") + } + + override fun zzl() { + throw AssertionError("Not expected") + } + + override fun zzm() { throw AssertionError("Not expected") } } diff --git a/paymentsheet-example/dependencies/dependencies.txt b/paymentsheet-example/dependencies/dependencies.txt index 2dd2b2a61af..a424b4e498d 100644 --- a/paymentsheet-example/dependencies/dependencies.txt +++ b/paymentsheet-example/dependencies/dependencies.txt @@ -23,7 +23,7 @@ | | | | | \--- androidx.collection:collection-ktx:1.3.0 -> 1.4.4 (c) | | | | +--- androidx.concurrent:concurrent-futures:1.0.0 -> 1.1.0 | | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.9.1 (*) -| | | | | \--- com.google.guava:listenablefuture:1.0 +| | | | | \--- com.google.guava:listenablefuture:1.0 -> 9999.0-empty-to-avoid-conflict-with-guava | | | | +--- androidx.core:core:1.1.0 -> 1.13.1 | | | | | +--- androidx.annotation:annotation:1.6.0 -> 1.9.1 (*) | | | | | +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*) @@ -74,7 +74,7 @@ | | | | | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.9.1 (*) | | | | | | | | \--- androidx.tracing:tracing:1.0.0 | | | | | | | | \--- androidx.annotation:annotation:1.1.0 -> 1.9.1 (*) -| | | | | | | \--- com.google.guava:listenablefuture:1.0 +| | | | | | | \--- com.google.guava:listenablefuture:1.0 -> 9999.0-empty-to-avoid-conflict-with-guava | | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.2.20 (*) | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.10.1 | | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*) @@ -99,7 +99,7 @@ | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.2.20 (*) | | | | | \--- androidx.core:core-ktx:1.13.1 (c) | | | | +--- androidx.interpolator:interpolator:1.0.0 (*) -| | | | \--- com.google.guava:listenablefuture:1.0 +| | | | \--- com.google.guava:listenablefuture:1.0 -> 9999.0-empty-to-avoid-conflict-with-guava | | | +--- com.google.dagger:dagger:2.55 | | | | +--- jakarta.inject:jakarta.inject-api:2.0.1 | | | | +--- javax.inject:javax.inject:1 @@ -812,7 +812,7 @@ | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 -> 1.9.24 (c) | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 -> 2.2.20 (c) | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22 -> 1.9.24 (c) -| | | | +--- com.google.errorprone:error_prone_annotations:2.15.0 +| | | | +--- com.google.errorprone:error_prone_annotations:2.15.0 -> 2.28.0 | | | | +--- androidx.activity:activity:1.8.0 -> 1.9.3 (*) | | | | +--- androidx.annotation:annotation:1.2.0 -> 1.9.1 (*) | | | | +--- androidx.appcompat:appcompat:1.6.1 -> 1.7.0 (*) @@ -853,7 +853,7 @@ | | | | | +--- androidx.core:core:1.7.0 -> 1.13.1 (*) | | | | | +--- androidx.customview:customview:1.0.0 -> 1.1.0 (*) | | | | | +--- androidx.customview:customview-poolingcontainer:1.0.0 (*) -| | | | | \--- androidx.viewpager2:viewpager2:1.1.0-beta02 (c) +| | | | | \--- androidx.viewpager2:viewpager2:1.1.0-beta02 -> 1.1.0 (c) | | | | +--- androidx.resourceinspection:resourceinspection-annotation:1.0.1 (*) | | | | +--- androidx.transition:transition:1.5.0 | | | | | +--- androidx.annotation:annotation:1.2.0 -> 1.9.1 (*) @@ -861,13 +861,13 @@ | | | | | +--- androidx.core:core:1.13.0 -> 1.13.1 (*) | | | | | \--- androidx.dynamicanimation:dynamicanimation:1.0.0 (*) | | | | +--- androidx.vectordrawable:vectordrawable:1.1.0 (*) -| | | | \--- androidx.viewpager2:viewpager2:1.0.0 -> 1.1.0-beta02 +| | | | \--- androidx.viewpager2:viewpager2:1.0.0 -> 1.1.0 | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.9.1 (*) -| | | | +--- androidx.annotation:annotation-experimental:1.3.0 -> 1.4.1 (*) +| | | | +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*) | | | | +--- androidx.collection:collection:1.1.0 -> 1.4.4 (*) | | | | +--- androidx.core:core:1.3.2 -> 1.13.1 (*) | | | | +--- androidx.fragment:fragment:1.1.0 -> 1.8.6 (*) -| | | | \--- androidx.recyclerview:recyclerview:1.3.1-rc01 -> 1.3.2 (*) +| | | | \--- androidx.recyclerview:recyclerview:1.3.1 -> 1.3.2 (*) | | | +--- androidx.lifecycle:lifecycle-livedata-ktx:2.8.7 | | | | +--- androidx.lifecycle:lifecycle-livedata:2.8.7 (*) | | | | +--- androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.7 (*) @@ -1220,13 +1220,27 @@ | \--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.21 -> 1.9.24 (*) +--- com.google.android.material:material:1.12.0 (*) +--- com.squareup.okio:okio:3.16.4 (*) -+--- com.google.android.libraries.places:places:3.5.0 ++--- com.google.android.libraries.places:places:5.0.0 | +--- androidx.appcompat:appcompat:1.0.0 -> 1.7.0 (*) | +--- androidx.cardview:cardview:1.0.0 (*) +| +--- androidx.constraintlayout:constraintlayout:2.1.4 -> 2.2.0 (*) +| +--- androidx.exifinterface:exifinterface:1.0.0 +| | \--- androidx.annotation:annotation:1.0.0 -> 1.9.1 (*) | +--- androidx.fragment:fragment:1.1.0 -> 1.8.6 (*) +| +--- androidx.lifecycle:lifecycle-runtime-ktx:2.8.7 (*) | +--- androidx.lifecycle:lifecycle-viewmodel:2.0.0 -> 2.8.7 (*) -| +--- androidx.recyclerview:recyclerview:1.0.0 -> 1.3.2 (*) +| +--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7 (*) +| +--- androidx.recyclerview:recyclerview:1.3.2 (*) +| +--- androidx.viewpager2:viewpager2:1.1.0 (*) | +--- com.android.volley:volley:1.2.1 +| +--- com.github.bumptech.glide:glide:4.11.0 +| | +--- com.github.bumptech.glide:gifdecoder:4.11.0 +| | | \--- androidx.annotation:annotation:1.0.0 -> 1.9.1 (*) +| | +--- com.github.bumptech.glide:disklrucache:4.11.0 +| | +--- com.github.bumptech.glide:annotations:4.11.0 +| | +--- androidx.fragment:fragment:1.0.0 -> 1.8.6 (*) +| | +--- androidx.vectordrawable:vectordrawable-animated:1.0.0 -> 1.1.0 (*) +| | \--- androidx.exifinterface:exifinterface:1.0.0 (*) | +--- com.google.android.datatransport:transport-api:3.1.0 | | \--- androidx.annotation:annotation:1.1.0 -> 1.9.1 (*) | +--- com.google.android.datatransport:transport-backend-cct:3.2.0 @@ -1246,19 +1260,29 @@ | | | \--- com.google.firebase:firebase-encoders:17.0.0 (*) | | \--- androidx.annotation:annotation:1.1.0 -> 1.9.1 (*) | +--- com.google.android.datatransport:transport-runtime:3.2.0 (*) -| +--- com.google.android.gms:play-services-base:18.3.0 -> 18.5.0 (*) -| +--- com.google.android.gms:play-services-basement:18.3.0 -> 18.4.0 (*) +| +--- com.google.android.gms:play-services-base:18.5.0 (*) +| +--- com.google.android.gms:play-services-basement:18.4.0 (*) | +--- com.google.android.gms:play-services-location:21.0.1 | | +--- com.google.android.gms:play-services-base:18.1.0 -> 18.5.0 (*) | | +--- com.google.android.gms:play-services-basement:18.1.0 -> 18.4.0 (*) | | \--- com.google.android.gms:play-services-tasks:18.0.2 -> 18.2.0 (*) | +--- com.google.android.gms:play-services-maps:17.0.0 -> 18.0.2 (*) -| +--- com.google.android.gms:play-services-tasks:18.1.0 -> 18.2.0 (*) +| +--- com.google.android.gms:play-services-tasks:18.2.0 (*) +| +--- com.google.android.material:material:1.12.0 (*) | +--- com.google.auto.value:auto-value-annotations:1.6.2 | +--- com.google.code.gson:gson:2.10 +| +--- com.google.guava:guava:33.3.0-android +| | +--- com.google.guava:failureaccess:1.0.2 +| | +--- com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava +| | +--- com.google.code.findbugs:jsr305:3.0.2 +| | +--- org.checkerframework:checker-qual:3.43.0 +| | \--- com.google.errorprone:error_prone_annotations:2.28.0 | +--- com.squareup.okhttp:okhttp:2.7.2 | | \--- com.squareup.okio:okio:1.6.0 -> 3.16.4 (*) -| \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.0 -> 2.2.20 (*) +| +--- org.jetbrains.kotlin:kotlin-stdlib:2.1.0 -> 2.2.20 (*) +| +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0 -> 1.10.1 (*) +| +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0 -> 1.10.1 (*) +| \--- org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.8.0 -> 1.10.1 (*) +--- com.squareup.retrofit2:converter-kotlinx-serialization:2.11.0 | +--- com.squareup.retrofit2:retrofit:2.11.0 | | \--- com.squareup.okhttp3:okhttp:3.14.9 -> 4.12.0 (*) diff --git a/paymentsheet-example/src/main/AndroidManifest.xml b/paymentsheet-example/src/main/AndroidManifest.xml index 30bf0cc02d0..0acf059cc6a 100644 --- a/paymentsheet-example/src/main/AndroidManifest.xml +++ b/paymentsheet-example/src/main/AndroidManifest.xml @@ -3,6 +3,7 @@ xmlns:tools="http://schemas.android.com/tools"> + - + + +