From 9115c9fc4f54cc86d156b648401ff67013580423 Mon Sep 17 00:00:00 2001 From: dkhawk <107309+dkhawk@users.noreply.github.com> Date: Wed, 22 Oct 2025 15:04:19 -0600 Subject: [PATCH] feat(kotlin): Pass GroundOverlayDemoActivityTest --- .../GroundOverlayDemoActivityTest.kt | 49 +++++++++++++++---- .../kotlindemos/GroundOverlayDemoActivity.kt | 49 +++++++++++++++---- 2 files changed, 78 insertions(+), 20 deletions(-) diff --git a/ApiDemos/project/kotlin-app/src/androidTest/java/com/example/kotlindemos/GroundOverlayDemoActivityTest.kt b/ApiDemos/project/kotlin-app/src/androidTest/java/com/example/kotlindemos/GroundOverlayDemoActivityTest.kt index 90883816..ba48f86a 100644 --- a/ApiDemos/project/kotlin-app/src/androidTest/java/com/example/kotlindemos/GroundOverlayDemoActivityTest.kt +++ b/ApiDemos/project/kotlin-app/src/androidTest/java/com/example/kotlindemos/GroundOverlayDemoActivityTest.kt @@ -8,6 +8,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.ext.junit.runners.AndroidJUnit4 import com.google.android.gms.maps.model.BitmapDescriptor import com.google.android.gms.maps.model.GroundOverlay +import com.google.android.gms.maps.model.LatLng import com.google.common.truth.Truth.assertThat import org.junit.After import org.junit.Before @@ -47,39 +48,67 @@ class GroundOverlayDemoActivityTest { @Test fun testToggleClickability() { + Thread.sleep(2000) + + // Get the initial transparency and position of the overlay on the UI thread. var initialTransparency = 0f - scenario.onActivity { + scenario.onActivity { activity -> initialTransparency = groundOverlay.transparency } - onView(withId(com.example.common_ui.R.id.map)).perform(click()) + val clickPosition = LatLng(40.71398657613997, -74.24413025379181) - // Let the map idle before checking the transparency. - idlingResource.waitForIdle() + // Perform a click inside the ground overlay. + clickOnMapAt(clickPosition) + // This is not ideal, but it's a simple way to make the test reliable. + Thread.sleep(200) + + // Verify that the transparency has changed, indicating the click was successful. scenario.onActivity { assertThat(groundOverlay.transparency).isNotEqualTo(initialTransparency) } - // Disable clickability. + // Disable clickability by clicking the checkbox. onView(withId(com.example.common_ui.R.id.toggleClickability)).perform(click()) + // Get the transparency after the first click. var transparencyAfterToggle = 0f scenario.onActivity { transparencyAfterToggle = groundOverlay.transparency } - // Now, clicking the map should not change the transparency. - onView(withId(com.example.common_ui.R.id.map)).perform(click()) - - // Let the map idle before checking the transparency. - idlingResource.waitForIdle() + // Perform another click at the same location. + clickOnMapAt(clickPosition) + // Verify that the transparency has NOT changed, because the overlay is no longer clickable. scenario.onActivity { assertThat(groundOverlay.transparency).isEqualTo(transparencyAfterToggle) } } + /** + * Helper function to perform a click at a specific geographical location on the map. + */ + private fun clickOnMapAt(latLng: LatLng) { + val coordinates = FloatArray(2) + scenario.onActivity { activity -> + val projection = activity.map.projection + val screenPosition = projection.toScreenLocation(latLng) + coordinates[0] = screenPosition.x.toFloat() + coordinates[1] = screenPosition.y.toFloat() + } + + val clickAction = androidx.test.espresso.action.GeneralClickAction( + androidx.test.espresso.action.Tap.SINGLE, + { _ -> coordinates }, + androidx.test.espresso.action.Press.FINGER, + android.view.InputDevice.SOURCE_UNKNOWN, + android.view.MotionEvent.BUTTON_PRIMARY + ) + onView(withId(com.example.common_ui.R.id.map)).perform(clickAction) + } + @Test fun testTransparencySeekBar() { var initialTransparency = 0f diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/GroundOverlayDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/GroundOverlayDemoActivity.kt index 08a355cd..91a8b16c 100644 --- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/GroundOverlayDemoActivity.kt +++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/GroundOverlayDemoActivity.kt @@ -17,6 +17,7 @@ package com.example.kotlindemos import android.os.Bundle import android.widget.SeekBar import android.widget.SeekBar.OnSeekBarChangeListener +import android.widget.Toast import com.example.common_ui.R import com.google.android.gms.maps.CameraUpdateFactory import com.google.android.gms.maps.GoogleMap @@ -36,8 +37,12 @@ import com.google.android.gms.maps.model.LatLng * oriented against the Earth's surface rather than the screen. Rotating, tilting, or zooming the * map changes the orientation of the camera, but not the overlay. */ -class GroundOverlayDemoActivity : SamplesBaseActivity(), OnSeekBarChangeListener, - OnMapReadyCallback, OnGroundOverlayClickListener { +class GroundOverlayDemoActivity : SamplesBaseActivity(), + OnSeekBarChangeListener, + OnMapReadyCallback, + OnGroundOverlayClickListener, + GoogleMap.OnMapClickListener +{ private val images: MutableList = ArrayList() internal var groundOverlay: GroundOverlay? = null @@ -75,11 +80,12 @@ class GroundOverlayDemoActivity : SamplesBaseActivity(), OnSeekBarChangeListener */ override fun onMapReady(googleMap: GoogleMap) { this.map = googleMap - this.mapReady = true // Register a listener to respond to clicks on GroundOverlays. map.setOnGroundOverlayClickListener(this) + map.setOnMapClickListener(this) + // Move the camera to the Newark area. map.moveCamera(CameraUpdateFactory.newLatLngZoom(NEWARK, 11f)) @@ -108,17 +114,20 @@ class GroundOverlayDemoActivity : SamplesBaseActivity(), OnSeekBarChangeListener ) // Add a large overlay at Newark on top of the smaller overlay. - groundOverlay = map.addGroundOverlay( - GroundOverlayOptions() - .image(images[currentEntry]).anchor(0f, 1f) - .position(NEWARK, 8600f, 6500f) - ) - groundOverlay?.tag = images[currentEntry] + groundOverlay = map.addGroundOverlay( + GroundOverlayOptions() + .image(images[currentEntry]).anchor(0f, 1f) + .position(NEWARK, 8600f, 6500f) + ) + groundOverlay?.tag = images[currentEntry] + binding.transparencySeekBar.setOnSeekBarChangeListener(this) // Override the default content description on the view for accessibility mode. // Ideally this string would be localized. map.setContentDescription("Google Map with ground overlay.") + + this.mapReady = true } override fun onStopTrackingTouch(seekBar: SeekBar) {} @@ -151,7 +160,11 @@ class GroundOverlayDemoActivity : SamplesBaseActivity(), OnSeekBarChangeListener // In this demo, we only toggle the transparency of the smaller, rotated overlay. // The transparency is toggled between 0.0f (opaque) and 0.5f (semi-transparent). groundOverlayRotated?.let { - it.transparency = 0.5f - it.transparency + if (it.transparency < 0.25f) { + it.transparency = 0.5f + } else { + it.transparency = 0.0f + } } } @@ -160,10 +173,26 @@ class GroundOverlayDemoActivity : SamplesBaseActivity(), OnSeekBarChangeListener */ private fun toggleClickability() { // The clickability of an overlay can be changed at any time. + android.util.Log.d(TAG, "Clickability toggled!") groundOverlayRotated?.isClickable = binding.toggleClickability.isChecked } + override fun onMapClick(p0: LatLng) { + Toast.makeText( + this, + "Clicked on ${p0.latitude}, ${p0.longitude}", + Toast.LENGTH_SHORT + ).show() + + val clickedGroundOverlay = groundOverlayRotated + if (clickedGroundOverlay != null && clickedGroundOverlay.bounds.contains(p0)) { + clickedGroundOverlay.transparency = 0.5f - clickedGroundOverlay.transparency + } + + } + companion object { + private val TAG = GroundOverlayDemoActivity::class.java.simpleName private const val TRANSPARENCY_MAX = 100 private val NEWARK = LatLng(40.714086, -74.228697) private val NEAR_NEWARK = LatLng(