From db84504da4b874de4ca50988b374941cdd95b3a8 Mon Sep 17 00:00:00 2001 From: Dale Hawkins <107309+dkhawk@users.noreply.github.com> Date: Tue, 9 Sep 2025 15:27:34 -0600 Subject: [PATCH 1/3] chore(deps): Bump dependency versions (#1594) * chore(deps): Bump dependency versions * chore: Upgrade Gradle wrapper to 8.14.3 --- gradle/libs.versions.toml | 14 +++++++------- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 61ddd0a0c..376ce95d1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,24 +3,24 @@ compileSdk = "36" targetSdk = "36" appcompat = "1.7.1" dokka-gradle-plugin = "2.0.0" -gradle = "8.10.1" +gradle = "8.13.0" jacoco-android = "0.2.1" lifecycle-extensions = "2.2.0" -lifecycle-viewmodel-ktx = "2.9.2" +lifecycle-viewmodel-ktx = "2.9.3" kotlin = "2.2.0" kotlinx-coroutines = "1.10.2" junit = "4.13.2" -mockito-core = "5.18.0" +mockito-core = "5.19.0" secrets-gradle-plugin = "2.0.1" truth = "1.4.4" play-services-maps = "19.2.0" -core-ktx = "1.16.0" -robolectric = "4.15.1" +core-ktx = "1.17.0" +robolectric = "4.16" kxml2 = "2.3.0" mockk = "1.14.5" -lint = "31.12.0" +lint = "31.13.0" org-jacoco-core = "0.8.13" -material = "1.12.0" +material = "1.13.0" gradleMavenPublishPlugin = "0.34.0" [libraries] diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e2847c820..d4081da47 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 23a4bb58229d0f81733afc1a42377e9d60f29f16 Mon Sep 17 00:00:00 2001 From: Dale Hawkins <107309+dkhawk@users.noreply.github.com> Date: Wed, 10 Sep 2025 11:28:17 -0600 Subject: [PATCH 2/3] feat(demo): Add StreetViewJavaHelper and demo and enable edge-to-edge (#1595) * feat(demo): Add Java demo for Street View utility This commit adds a new demo activity written in Java to demonstrate the usage of the Street View utility. To facilitate this, a Kotlin helper has been introduced to bridge the gap between suspend functions and Java's callback-based asynchronous model. The key changes are: - **`StreetViewDemoActivityJava`**: A new demo activity that shows how to check for Street View availability from Java. - **`StreetViewHelper`**: A Kotlin object that wraps the `suspend` function `StreetViewUtils.fetchStreetViewData` and exposes it to Java consumers via a callback interface. - **`ApiKeyValidator`**: A new utility class to check for a valid Maps API key within the demo application. - **Unit Tests**: Added tests for `StreetViewHelper` using Robolectric, MockK, and coroutine testing libraries to verify its behavior. - **Dependencies**: Added `mockk`, `kotlinx-coroutines-test`, and `robolectric` to the demo module's test dependencies. * feat(demo): Enable edge-to-edge for StreetView demo activities This commit refactors the `StreetViewDemoActivity` in both its Kotlin and Java versions to support edge-to-edge display. The key changes include: - Changing the base class from `Activity` to `AppCompatActivity`. - Using `WindowCompat.setDecorFitsSystemWindows` to allow the app to draw behind the system bars. - Adding an `OnApplyWindowInsetsListener` to the root view to apply padding for the system bars, preventing content from being obscured. - Updating the `street_view_demo.xml` layout with an ID for the root view to facilitate the insets listener. - Updating the copyright year. * refactor(library): Move StreetViewJavaHelper to library module This commit moves the `StreetViewHelper` from the `demo` module to the `library` module, making it an officially supported utility for Java consumers. The key changes include: - Renaming `StreetViewHelper` to `StreetViewJavaHelper` for better clarity and moving it to the `com.google.maps.android` package within the library. - Migrating the corresponding unit tests from the `demo` to the `library` module and updating them to reflect the class rename. - Adjusting `build.gradle.kts` files to move test dependencies (`mockk`, `coroutines-test`, `robolectric`) from the `demo` to the `library` module. - Renaming `StreetViewDemoActivityJava` to `StreetViewDemoJavaActivity` and updating it to use the new helper from the library. - Improving the warning message for invalid or missing API keys in the demo app. * refactor: Remove redundant Javadoc in StreetViewDemoJavaActivity --- demo/src/main/AndroidManifest.xml | 3 + .../android/utils/demo/ApiKeyValidator.java | 63 +++++++++++ .../maps/android/utils/demo/MainActivity.java | 1 + .../utils/demo/StreetViewDemoActivity.kt | 40 +++++-- .../demo/StreetViewDemoJavaActivity.java | 104 ++++++++++++++++++ demo/src/main/res/layout/street_view_demo.xml | 1 + demo/src/main/res/values/strings.xml | 2 +- gradle/libs.versions.toml | 1 + library/build.gradle.kts | 4 + .../maps/android/StreetViewJavaHelper.kt | 64 +++++++++++ .../maps/android/StreetViewHelperTest.kt | 94 ++++++++++++++++ 11 files changed, 369 insertions(+), 8 deletions(-) create mode 100644 demo/src/main/java/com/google/maps/android/utils/demo/ApiKeyValidator.java create mode 100644 demo/src/main/java/com/google/maps/android/utils/demo/StreetViewDemoJavaActivity.java create mode 100644 library/src/main/java/com/google/maps/android/StreetViewJavaHelper.kt create mode 100644 library/src/test/java/com/google/maps/android/StreetViewHelperTest.kt diff --git a/demo/src/main/AndroidManifest.xml b/demo/src/main/AndroidManifest.xml index fcf52fa22..4d359efca 100644 --- a/demo/src/main/AndroidManifest.xml +++ b/demo/src/main/AndroidManifest.xml @@ -124,6 +124,9 @@ + diff --git a/demo/src/main/java/com/google/maps/android/utils/demo/ApiKeyValidator.java b/demo/src/main/java/com/google/maps/android/utils/demo/ApiKeyValidator.java new file mode 100644 index 000000000..9acd9a066 --- /dev/null +++ b/demo/src/main/java/com/google/maps/android/utils/demo/ApiKeyValidator.java @@ -0,0 +1,63 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES, OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.maps.android.utils.demo; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.os.Bundle; + +import java.util.regex.Pattern; + +/** + * A utility class to validate the Maps API key. The purpose of this check is to ensure that a + * developer has set a valid-looking key. This is not a definitive check, and there is a + * possibility of a false negative. If you are sure your key is correct, you can remove this + * check. + */ +class ApiKeyValidator { + private static final String REGEX = "^AIza[0-9A-Za-z-_]{35}$"; + private static final Pattern PATTERN = Pattern.compile(REGEX); + + /** + * Checks if the provided context has a valid Google Maps API key in its metadata. + * + * @param context The context to check for the API key. + * @return `true` if the context has a valid API key, `false` otherwise. + */ + static boolean hasMapsApiKey(Context context) { + String mapsApiKey = getMapsApiKey(context); + return mapsApiKey != null && PATTERN.matcher(mapsApiKey).matches(); + } + + /** + * Retrieves the Google Maps API key from the application metadata. + * + * @param context The context to retrieve the API key from. + * @return The API key if found, `null` otherwise. + */ + private static String getMapsApiKey(Context context) { + try { + Bundle bundle = context.getPackageManager() + .getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA) + .metaData; + return bundle.getString("com.google.android.geo.API_KEY"); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + return null; + } + } +} diff --git a/demo/src/main/java/com/google/maps/android/utils/demo/MainActivity.java b/demo/src/main/java/com/google/maps/android/utils/demo/MainActivity.java index df2579e69..fa0ec0e42 100644 --- a/demo/src/main/java/com/google/maps/android/utils/demo/MainActivity.java +++ b/demo/src/main/java/com/google/maps/android/utils/demo/MainActivity.java @@ -87,6 +87,7 @@ protected void onCreate(Bundle savedInstanceState) { addDemo("Multi Layer", MultiLayerDemoActivity.class); addDemo("AnimationUtil sample", AnimationUtilDemoActivity.class); addDemo("Street View Demo", StreetViewDemoActivity.class); + addDemo("Street View Demo (Java)", StreetViewDemoJavaActivity.class); } private void addDemo(String demoName, Class activityClass) { diff --git a/demo/src/main/java/com/google/maps/android/utils/demo/StreetViewDemoActivity.kt b/demo/src/main/java/com/google/maps/android/utils/demo/StreetViewDemoActivity.kt index 432be2416..20c7c4418 100644 --- a/demo/src/main/java/com/google/maps/android/utils/demo/StreetViewDemoActivity.kt +++ b/demo/src/main/java/com/google/maps/android/utils/demo/StreetViewDemoActivity.kt @@ -1,5 +1,5 @@ /* - * Copyright 2024 Google LLC + * Copyright 2025 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,35 +17,61 @@ package com.google.maps.android.utils.demo import android.annotation.SuppressLint -import android.app.Activity import android.os.Bundle import android.widget.TextView import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.ViewCompat +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.lifecycle.lifecycleScope import com.google.android.gms.maps.model.LatLng import com.google.maps.android.StreetViewUtils -import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch -class StreetViewDemoActivity : Activity() { +/** + * An activity that demonstrates how to use the [StreetViewUtils] to check for Street View + * availability at different locations. + * + * This activity performs the following actions: + * 1. Sets up the layout to fit system windows. + * 2. Checks if a valid Google Maps API key is present. + * 3. Launches a coroutine to fetch Street View data for two predefined locations. + * 4. Displays the results of the Street View data fetch on the screen. + */ +class StreetViewDemoActivity : AppCompatActivity() { @SuppressLint("SetTextI18n") - @OptIn(DelicateCoroutinesApi::class) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + // Make the activity content fit behind the system bars. + WindowCompat.setDecorFitsSystemWindows(window, false) setContentView(R.layout.street_view_demo) + // Apply window insets to the main view to avoid content overlapping with system bars. + ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> + val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) + insets + } + + // Check for a valid Maps API key before proceeding. if (!hasMapsApiKey(this)) { Toast.makeText(this, R.string.bad_maps_api_key, Toast.LENGTH_LONG).show() finish() + return // Return early to prevent further execution } - GlobalScope.launch(Dispatchers.Main) { + // Launch a coroutine in the Main dispatcher to fetch Street View data and update the UI. + lifecycleScope.launch(Dispatchers.Main) { + // Fetch Street View data for the first location (which is expected to be supported). val response1 = StreetViewUtils.fetchStreetViewData(LatLng(48.1425918, 11.5386121), BuildConfig.MAPS_API_KEY) + // Fetch Street View data for the second location (which is expected to be unsupported). val response2 = StreetViewUtils.fetchStreetViewData(LatLng(8.1425918, 11.5386121), BuildConfig.MAPS_API_KEY) + // Update the UI with the results. findViewById(R.id.textViewFirstLocation).text = "Location 1 is supported in StreetView: $response1" findViewById(R.id.textViewSecondLocation).text = "Location 2 is supported in StreetView: $response2" } diff --git a/demo/src/main/java/com/google/maps/android/utils/demo/StreetViewDemoJavaActivity.java b/demo/src/main/java/com/google/maps/android/utils/demo/StreetViewDemoJavaActivity.java new file mode 100644 index 000000000..2260dca4f --- /dev/null +++ b/demo/src/main/java/com/google/maps/android/utils/demo/StreetViewDemoJavaActivity.java @@ -0,0 +1,104 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.maps.android.utils.demo; + +import android.annotation.SuppressLint; +import android.os.Bundle; +import android.util.Log; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowCompat; +import androidx.core.view.WindowInsetsCompat; + +import com.google.android.gms.maps.model.LatLng; +import com.google.maps.android.Status; +import com.google.maps.android.StreetViewJavaHelper; + +/** + * An activity that demonstrates how to use the Street View utility in Java to check for Street View + * availability at different locations. + *

+ * This activity performs the following actions: + * 1. Sets up the layout to fit system windows. + * 2. Checks if a valid Google Maps API key is present. + * 3. Fetches Street View data for two predefined locations using asynchronous callbacks. + * 4. Displays the results of the Street View data fetch on the screen. + */ +public class StreetViewDemoJavaActivity extends AppCompatActivity { + + @SuppressLint("SetTextI18n") + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + // Make the activity content fit behind the system bars. + WindowCompat.setDecorFitsSystemWindows(getWindow(), false); + setContentView(R.layout.street_view_demo); + + // Apply window insets to the main view to avoid content overlapping with system bars. + ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insetsCompat) -> { + Insets insets = insetsCompat.getInsets(WindowInsetsCompat.Type.systemBars()); + v.setPadding(insets.left, insets.top, insets.right, insets.bottom); + return insetsCompat; + }); + + // Check for a valid Maps API key before proceeding. + if (!ApiKeyValidator.hasMapsApiKey(this)) { + Toast.makeText(this, R.string.bad_maps_api_key, Toast.LENGTH_LONG).show(); + finish(); + return; // Return early to prevent further execution + } + + // Fetches Street View data for the first location (expected to be supported). + StreetViewJavaHelper.fetchStreetViewData( + new LatLng(48.1425918, 11.5386121), + BuildConfig.MAPS_API_KEY, new StreetViewJavaHelper.StreetViewCallback() { + @Override + public void onStreetViewResult(@NonNull Status status) { + // Updates the UI with the result on the UI thread. + runOnUiThread(() -> ((TextView) findViewById(R.id.textViewFirstLocation)).setText("Location 1 is supported in StreetView: " + status)); + } + + @Override + public void onStreetViewError(@NonNull Exception e) { + // Handles the error by printing stack trace and showing a toast. + Log.w("SVJDemo", "Error fetching Street View data: " + e.getMessage()); + Toast.makeText(StreetViewDemoJavaActivity.this, "Error fetching Street View data: " + e.getMessage(), Toast.LENGTH_SHORT).show(); + } + }); + + // Fetches Street View data for the second location (expected to be unsupported). + StreetViewJavaHelper.fetchStreetViewData(new LatLng(8.1425918, 11.5386121), BuildConfig.MAPS_API_KEY, new StreetViewJavaHelper.StreetViewCallback() { + @Override + public void onStreetViewResult(@NonNull Status status) { + // Updates the UI with the result on the UI thread. + runOnUiThread(() -> ((TextView) findViewById(R.id.textViewSecondLocation)).setText("Location 2 is supported in StreetView: " + status)); + } + + @Override + public void onStreetViewError(@NonNull Exception e) { + // Handles the error by printing stack trace and showing a toast. + Log.w("SVJDemo", "Error fetching Street View data: " + e.getMessage()); + Toast.makeText(StreetViewDemoJavaActivity.this, "Error fetching Street View data: " + e.getMessage(), Toast.LENGTH_SHORT).show(); + } + }); + } +} \ No newline at end of file diff --git a/demo/src/main/res/layout/street_view_demo.xml b/demo/src/main/res/layout/street_view_demo.xml index df7b93a39..5a948f6ca 100644 --- a/demo/src/main/res/layout/street_view_demo.xml +++ b/demo/src/main/res/layout/street_view_demo.xml @@ -16,6 +16,7 @@ --> diff --git a/demo/src/main/res/values/strings.xml b/demo/src/main/res/values/strings.xml index f910616d2..a0c3d7efb 100644 --- a/demo/src/main/res/values/strings.xml +++ b/demo/src/main/res/values/strings.xml @@ -33,5 +33,5 @@ Radius Gradient Opacity - Invalid or missing Google Maps API key + The Google Maps API key looks invalid or is missing. If you are sure your key is correct, you can remove this check from the demo. diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 376ce95d1..f08d27766 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -35,6 +35,7 @@ lifecycle-viewmodel-ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx kotlin-stdlib-jdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref = "kotlin" } kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" } kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" } +kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" } junit = { module = "junit:junit", version.ref = "junit" } mockito-core = { module = "org.mockito:mockito-core", version.ref = "mockito-core" } secrets-gradle-plugin = { module = "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin", version.ref = "secrets-gradle-plugin" } diff --git a/library/build.gradle.kts b/library/build.gradle.kts index 5b1f841a4..dd4edcc74 100644 --- a/library/build.gradle.kts +++ b/library/build.gradle.kts @@ -71,6 +71,10 @@ dependencies { testImplementation(libs.kotlin.test) testImplementation(libs.truth) implementation(libs.kotlin.stdlib.jdk8) + + testImplementation(libs.mockk) + testImplementation(libs.kotlinx.coroutines.test) + testImplementation(libs.robolectric) } tasks.register("instrumentTest") { diff --git a/library/src/main/java/com/google/maps/android/StreetViewJavaHelper.kt b/library/src/main/java/com/google/maps/android/StreetViewJavaHelper.kt new file mode 100644 index 000000000..0816a6a2e --- /dev/null +++ b/library/src/main/java/com/google/maps/android/StreetViewJavaHelper.kt @@ -0,0 +1,64 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.maps.android + +import com.google.android.gms.maps.model.LatLng +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +/** + * A helper object to call the suspend function `fetchStreetViewData` from Java. + */ +object StreetViewJavaHelper { + /** + * A callback interface to receive the result of the Street View data fetch. + */ + interface StreetViewCallback { + /** + * Called when the Street View data is fetched successfully. + * + * @param status The status of the Street View data. + */ + fun onStreetViewResult(status: Status) + + /** + * Called when there is an error fetching the Street View data. + * + * @param e The exception that occurred. + */ + fun onStreetViewError(e: Exception) + } + + /** + * Fetches Street View data for the given location and returns the result via a callback. + * + * @param latLng The location to fetch Street View data for. + * @param apiKey The API key to use for the request. + * @param callback The callback to receive the result. + */ + @JvmStatic + fun fetchStreetViewData(latLng: LatLng, apiKey: String, callback: StreetViewCallback) { + CoroutineScope(Dispatchers.Main).launch { + try { + val status = StreetViewUtils.fetchStreetViewData(latLng, apiKey) + callback.onStreetViewResult(status) + } catch (e: Exception) { + callback.onStreetViewError(e) + } + } + } +} diff --git a/library/src/test/java/com/google/maps/android/StreetViewHelperTest.kt b/library/src/test/java/com/google/maps/android/StreetViewHelperTest.kt new file mode 100644 index 000000000..9071e7640 --- /dev/null +++ b/library/src/test/java/com/google/maps/android/StreetViewHelperTest.kt @@ -0,0 +1,94 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.maps.android + +import com.google.android.gms.maps.model.LatLng +import io.mockk.coEvery +import io.mockk.mockk +import io.mockk.mockkObject +import io.mockk.verify +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.test.setMain +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner + +/** + * Tests for [StreetViewJavaHelper]. + */ +@ExperimentalCoroutinesApi +@RunWith(RobolectricTestRunner::class) +class StreetViewHelperTest { + + private val testDispatcher = StandardTestDispatcher() + + @Before + fun setUp() { + Dispatchers.setMain(testDispatcher) + mockkObject(StreetViewUtils) + } + + @After + fun tearDown() { + Dispatchers.resetMain() + } + + /** + * Tests that [StreetViewJavaHelper.fetchStreetViewData] calls the onStreetViewResult callback with the OK status when the call is successful. + */ + @Test + fun `fetchStreetViewData should call onStreetViewResult with OK status`() = runTest { + // Arrange + val latLng = LatLng(1.0, 2.0) + val apiKey = "some_api_key" + val callback = mockk(relaxed = true) + coEvery { StreetViewUtils.fetchStreetViewData(latLng, apiKey) } returns Status.OK + + // Act + StreetViewJavaHelper.fetchStreetViewData(latLng, apiKey, callback) + testDispatcher.scheduler.advanceUntilIdle() + + // Assert + verify { callback.onStreetViewResult(Status.OK) } + } + + /** + * Tests that [StreetViewJavaHelper.fetchStreetViewData] calls the onStreetViewError callback when an exception occurs. + */ + @Test + fun `fetchStreetViewData should call onStreetViewError when an exception occurs`() = runTest { + // Arrange + val latLng = LatLng(1.0, 2.0) + val apiKey = "some_api_key" + val callback = mockk(relaxed = true) + val exception = Exception("some_error") + coEvery { StreetViewUtils.fetchStreetViewData(latLng, apiKey) } throws exception + + // Act + StreetViewJavaHelper.fetchStreetViewData(latLng, apiKey, callback) + testDispatcher.scheduler.advanceUntilIdle() + + // Assert + verify { callback.onStreetViewError(exception) } + } +} \ No newline at end of file From 49c06c7a219e6665a6bd53bed85ae02a7e3c0e15 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 10 Sep 2025 17:34:46 +0000 Subject: [PATCH 3/3] chore(release): 3.17.0 [skip ci] # [3.17.0](https://github.com/googlemaps/android-maps-utils/compare/v3.16.2...v3.17.0) (2025-09-10) ### Features * **demo:** Add StreetViewJavaHelper and demo and enable edge-to-edge ([#1595](https://github.com/googlemaps/android-maps-utils/issues/1595)) ([23a4bb5](https://github.com/googlemaps/android-maps-utils/commit/23a4bb58229d0f81733afc1a42377e9d60f29f16)) --- README.md | 2 +- build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5a9afab6f..a66e9537f 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ dependencies { // Utilities for Maps SDK for Android (requires Google Play Services) // You do not need to add a separate dependency for the Maps SDK for Android // since this library builds in the compatible version of the Maps SDK. - implementation 'com.google.maps.android:android-maps-utils:3.16.2' + implementation 'com.google.maps.android:android-maps-utils:3.17.0' // Optionally add the Kotlin Extensions (KTX) for full Kotlin language support // See latest version at https://github.com/googlemaps/android-maps-ktx diff --git a/build.gradle.kts b/build.gradle.kts index 85a3ddc19..640f47758 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -37,5 +37,5 @@ tasks.register("clean") { allprojects { group = "com.google.maps.android" - version = "3.16.2" + version = "3.17.0" } \ No newline at end of file