KEMBAR78
feat: Introduce a robust Google Maps initializer by dkhawk · Pull Request #758 · googlemaps/android-maps-compose · GitHub
Skip to content

Conversation

dkhawk
Copy link
Collaborator

@dkhawk dkhawk commented Sep 8, 2025

This commit refactors the map initialization logic to be more robust and
test-friendly.

Previously, the map initialization was coupled with the attribution ID
logic, which made it difficult to handle initialization failures,
especially in test environments where the Maps SDK might be mocked.

This change introduces a new GoogleMapsInitializer object that manages
the initialization process with a state machine. This provides more
control over the initialization process and allows for better error
handling.

The key changes are:

  • A new GoogleMapsInitializer object that manages the initialization
    of the Google Maps SDK.
  • An InitializationState enum that represents the different states of
    the initialization process.
  • An initialize function that starts the initialization process on a
    background thread.
  • A reset function that allows for re-initialization in test
    environments.
  • The GoogleMap composable now uses the GoogleMapsInitializer to
    ensure that the map is only displayed after the SDK has been
    successfully initialized.

Two new tests have been added to verify the new logic:

  • A unit test (GoogleMapsInitializerTest) that runs in a local JVM
    and asserts that the initialization fails as expected when Google
    Play services are not available.
  • An instrumentation test (GoogleMapsInitializerTest) that runs on an
    Android device or emulator and asserts that the initialization
    succeeds as expected when Google Play services are available.

This commit refactors the map initialization logic to be more robust and
test-friendly.

Previously, the map initialization was coupled with the attribution ID
logic, which made it difficult to handle initialization failures,
especially in test environments where the Maps SDK might be mocked.

This change introduces a new `GoogleMapsInitializer` object that manages
the initialization process with a state machine. This provides more
control over the initialization process and allows for better error
handling.

The key changes are:

- A new `GoogleMapsInitializer` object that manages the initialization
  of the Google Maps SDK.
- An `InitializationState` enum that represents the different states of
  the initialization process.
- An `initialize` function that starts the initialization process on a
  background thread.
- A `reset` function that allows for re-initialization in test
  environments.
- The `GoogleMap` composable now uses the `GoogleMapsInitializer` to
  ensure that the map is only displayed after the SDK has been
  successfully initialized.
@dkhawk dkhawk requested a review from kikoso September 8, 2025 22:32
This change refactors the `GoogleMapsInitializer` to use suspend functions for initialization and reset operations, improving its testability and adherence to structured concurrency.

Key changes:
- Converted `GoogleMapsInitializer.initialize()` and `GoogleMapsInitializer.reset()` to `suspend` functions.
- Removed the internal `CoroutineScope` and job management from `GoogleMapsInitializer`.
- Updated unit and instrumentation tests to use `runTest` from `kotlinx-coroutines-test`, removing the need for `Thread.sleep()`.
- Added the `kotlinx-coroutines-test` dependency to the `maps-app` module.
The `initialize` function has been refactored to be a fully suspending operation.

Key changes:
- Replaced `launch(Dispatchers.IO)` with `withContext(Dispatchers.IO)`. This ensures the `initialize` function suspends until the blocking initialization call is complete, rather than returning immediately.
- Added explicit handling for non-SUCCESS results from `MapsInitializer.initialize()` to set the state to `FAILURE`.
- Restructured the `try-catch` block to correctly handle exceptions from the `withContext` block.
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(AndroidJUnit4::class)
class GoogleMapsInitializerTest {

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a random idea: since one of the motivations to do some work on the Maps Initializer was the positive we got on the StrictMode, wondering if it could make sense to test this with the StrictMode activated:

    @Before
    fun setUp() {
        StrictMode.setThreadPolicy(
            StrictMode.ThreadPolicy.Builder()
                .detectDiskReads()
                .detectAll()
                .penaltyLog()
                .build()
        )
        StrictMode.setVmPolicy(
            StrictMode.VmPolicy.Builder()
                .detectAll()
                .penaltyLog()
                .build()
        )
    }

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good idea. Thanks for the suggestion!

Copy link
Collaborator

@kikoso kikoso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! This approach is much better.

Wraps the `GoogleMapsInitializer.initialize()` call with strict
StrictMode policies. This ensures the initialization process does not
perform any violations, such as disk reads, which would cause the
test to fail.
Key changes:
- Introduced a custom `LatLngSubject` for the Truth assertion library to allow for `LatLng` comparisons with a tolerance.
- Migrated assertions in `GoogleMapViewTests` from JUnit to Truth for improved readability and more expressive tests.
- Added explicit Google Maps SDK initialization within the test setup.
@googlemaps-bot
Copy link
Contributor

Code Coverage

There is no coverage information present for the Files changed

@dkhawk dkhawk merged commit 87a4b5c into main Sep 9, 2025
10 checks passed
@dkhawk dkhawk deleted the feat/maps-initializer branch September 9, 2025 15:59
googlemaps-bot pushed a commit that referenced this pull request Sep 9, 2025
# [6.10.0](v6.9.0...v6.10.0) (2025-09-09)

### Features

* Introduce a robust Google Maps initializer ([#758](#758)) ([87a4b5c](87a4b5c))
@googlemaps-bot
Copy link
Contributor

🎉 This PR is included in version 6.10.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants