diff --git a/play-services-maps/core/hms/src/main/kotlin/org/microg/gms/maps/hms/GoogleMap.kt b/play-services-maps/core/hms/src/main/kotlin/org/microg/gms/maps/hms/GoogleMap.kt index ad1714aa3..d12096dac 100644 --- a/play-services-maps/core/hms/src/main/kotlin/org/microg/gms/maps/hms/GoogleMap.kt +++ b/play-services-maps/core/hms/src/main/kotlin/org/microg/gms/maps/hms/GoogleMap.kt @@ -298,12 +298,13 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) it.setContentDescription(desc) } - override fun getUiSettings(): IUiSettingsDelegate? = map?.uiSettings?.let { UiSettingsImpl(it) } + override fun getUiSettings(): IUiSettingsDelegate = + map?.uiSettings?.let { UiSettingsImpl(it) } ?: UiSettingsCache().also { + internalOnInitializedCallbackList.add(it.getMapReadyCallback()) + } - override fun getProjection(): IProjectionDelegate? = map?.projection?.let { - Log.d(TAG, "getProjection") - ProjectionImpl(it) - } + override fun getProjection(): IProjectionDelegate = + map?.projection?.let { ProjectionImpl(it) } ?: DummyProjection() override fun setOnCameraChangeListener(listener: IOnCameraChangeListener?) = afterInitialize { Log.d(TAG, "setOnCameraChangeListener"); @@ -555,18 +556,13 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) override fun onCreate(savedInstanceState: Bundle?) { if (!created) { - Log.d(TAG, "create: ${context.packageName},\n$options") + Log.d(TAG_LOGO, "create: ${context.packageName},\n$options") val mapContext = MapContext(context) MapsInitializer.initialize(mapContext) val mapView = MapView(mapContext, options.toHms()) this.mapView = mapView view.addView(mapView) mapView.onCreate(savedInstanceState?.toHms()) - view.viewTreeObserver.addOnGlobalLayoutListener { - if (!isFakeWatermark) { - fakeWatermark() - } - } mapView.getMapAsync(this::initMap) created = true @@ -574,22 +570,17 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } } - private var isFakeWatermark: Boolean = false - private fun fakeWatermark() { - Log.d(TAG_LOGO, "start") - try { - val view1 = view.getChildAt(0) as ViewGroup - val view2 = view1.getChildAt(0) as ViewGroup - val view4 = view2.getChildAt(1) - Log.d(TAG_LOGO, view4.toString()) - if (view4 is LinearLayout) { - view4.visibility = View.GONE - isFakeWatermark = true - } else { - throw Exception("LinearLayout not found") - } - } catch (tr: Throwable) { - Log.d(TAG_LOGO, "Throwable", tr) + private fun fakeWatermark(method: () -> Unit) { + Log.d(TAG_LOGO, "start -> $view") + val view1 = view.getChildAt(0) as? ViewGroup + val view2 = view1?.getChildAt(0) as? ViewGroup + val view4 = view2?.getChildAt(1) + Log.d(TAG_LOGO, view4?.toString() ?: "view4 is null") + if (view4 is LinearLayout) { + view4.visibility = View.GONE + method() + } else { + Log.d(TAG_LOGO, "LinearLayout not found") } } @@ -696,6 +687,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) callback.onMapReady(map) } internalOnInitializedCallbackList.clear() + fakeWatermark { Log.d(TAG_LOGO, "fakeWatermark success") } } tryRunUserInitializedCallbacks(tag = "initMap") diff --git a/play-services-maps/core/hms/src/main/kotlin/org/microg/gms/maps/hms/Projection.kt b/play-services-maps/core/hms/src/main/kotlin/org/microg/gms/maps/hms/Projection.kt index bac205d31..2fdbe6f20 100644 --- a/play-services-maps/core/hms/src/main/kotlin/org/microg/gms/maps/hms/Projection.kt +++ b/play-services-maps/core/hms/src/main/kotlin/org/microg/gms/maps/hms/Projection.kt @@ -12,11 +12,14 @@ import com.google.android.gms.dynamic.ObjectWrapper import com.google.android.gms.dynamic.unwrap import com.google.android.gms.maps.internal.IProjectionDelegate import com.google.android.gms.maps.model.LatLng +import com.google.android.gms.maps.model.LatLngBounds import com.google.android.gms.maps.model.VisibleRegion import com.huawei.hms.maps.Projection import org.microg.gms.maps.hms.utils.toGms import org.microg.gms.maps.hms.utils.toHms +private const val TAG = "GmsMapProjection" + class ProjectionImpl(private val projection: Projection) : IProjectionDelegate.Stub() { private var lastVisibleRegion: VisibleRegion? = null @@ -54,8 +57,21 @@ class ProjectionImpl(private val projection: Projection) : IProjectionDelegate.S Log.d(TAG, "getVisibleRegion: $visibleRegion") return lastVisibleRegion } +} - companion object { - private val TAG = "GmsMapProjection" +class DummyProjection : IProjectionDelegate.Stub() { + override fun fromScreenLocation(obj: IObjectWrapper?): LatLng { + Log.d(TAG, "Map not initialized when calling getProjection(). Cannot calculate fromScreenLocation") + return LatLng(0.0, 0.0) } -} + + override fun toScreenLocation(latLng: LatLng?): IObjectWrapper { + Log.d(TAG, "Map not initialized when calling getProjection(). Cannot calculate toScreenLocation") + return ObjectWrapper.wrap(Point(0, 0)) + } + + override fun getVisibleRegion(): VisibleRegion { + Log.d(TAG, "Map not initialized when calling getProjection(). Cannot calculate getVisibleRegion") + return VisibleRegion(LatLngBounds(LatLng(0.0, 0.0), LatLng(0.0, 0.0))) + } +} \ No newline at end of file diff --git a/play-services-maps/core/hms/src/main/kotlin/org/microg/gms/maps/hms/UiSettings.kt b/play-services-maps/core/hms/src/main/kotlin/org/microg/gms/maps/hms/UiSettings.kt index 335064c14..5ca46ce12 100644 --- a/play-services-maps/core/hms/src/main/kotlin/org/microg/gms/maps/hms/UiSettings.kt +++ b/play-services-maps/core/hms/src/main/kotlin/org/microg/gms/maps/hms/UiSettings.kt @@ -9,8 +9,61 @@ import android.os.Parcel import android.util.Log import com.google.android.gms.maps.internal.IUiSettingsDelegate +import com.huawei.hms.maps.OnMapReadyCallback import com.huawei.hms.maps.UiSettings +private const val TAG = "GmsMapsUiSettings" + +/** + * This class "implements" unimplemented methods to avoid duplication in subclasses + */ +abstract class AbstractUiSettings : IUiSettingsDelegate.Stub() { + override fun setZoomControlsEnabled(zoom: Boolean) { + Log.d(TAG, "unimplemented Method: setZoomControlsEnabled") + } + + override fun setMyLocationButtonEnabled(locationButton: Boolean) { + Log.d(TAG, "unimplemented Method: setMyLocationButtonEnabled") + } + + override fun isZoomControlsEnabled(): Boolean { + Log.d(TAG, "unimplemented Method: isZoomControlsEnabled") + return false + } + + override fun isMyLocationButtonEnabled(): Boolean { + Log.d(TAG, "unimplemented Method: isMyLocationButtonEnabled") + return false + } + + override fun setIndoorLevelPickerEnabled(indoorLevelPicker: Boolean) { + Log.d(TAG, "unimplemented Method: setIndoorLevelPickerEnabled") + } + + override fun isIndoorLevelPickerEnabled(): Boolean { + Log.d(TAG, "unimplemented Method: isIndoorLevelPickerEnabled") + return false + } + + override fun setMapToolbarEnabled(mapToolbar: Boolean) { + Log.d(TAG, "unimplemented Method: setMapToolbarEnabled") + } + + override fun isMapToolbarEnabled(): Boolean { + Log.d(TAG, "unimplemented Method: isMapToolbarEnabled") + return false + } + + override fun setScrollGesturesEnabledDuringRotateOrZoom(scrollDuringZoom: Boolean) { + Log.d(TAG, "unimplemented Method: setScrollGesturesEnabledDuringRotateOrZoom") + } + + override fun isScrollGesturesEnabledDuringRotateOrZoom(): Boolean { + Log.d(TAG, "unimplemented Method: isScrollGesturesEnabledDuringRotateOrZoom") + return true + } +} + class UiSettingsImpl(private val uiSettings: UiSettings) : IUiSettingsDelegate.Stub() { override fun setZoomControlsEnabled(zoom: Boolean) { @@ -97,13 +150,144 @@ class UiSettingsImpl(private val uiSettings: UiSettings) : IUiSettingsDelegate.S } override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean = - if (super.onTransact(code, data, reply, flags)) { - true - } else { - Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false - } - - companion object { - private val TAG = "GmsMapsUi" + if (super.onTransact(code, data, reply, flags)) { + true + } else { + Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false + } +} + +class UiSettingsCache : AbstractUiSettings() { + + private var compass: Boolean? = null + private var scrollGestures: Boolean? = null + private var zoomGestures: Boolean? = null + private var tiltGestures: Boolean? = null + private var rotateGestures: Boolean? = null + private var otherGestures: Boolean? = null + + private var isZoomControlsEnabled: Boolean? = null + private var isMyLocationButtonEnabled: Boolean? = null + private var isAllGesturesEnabled: Boolean? = null + private var isIndoorLevelPickerEnabled: Boolean? = null + private var isMapToolbarEnabled: Boolean? = null + private var isScrollGesturesEnabledDuringRotateOrZoom: Boolean? = null + + override fun setMapToolbarEnabled(mapToolbar: Boolean) { + Log.d(TAG, "setMapToolbarEnabled: $mapToolbar") + this.isMapToolbarEnabled = mapToolbar + } + + override fun isMapToolbarEnabled(): Boolean { + Log.d(TAG, "isMapToolbarEnabled") + return isMapToolbarEnabled ?: true + } + + override fun setScrollGesturesEnabledDuringRotateOrZoom(scrollDuringZoom: Boolean) { + Log.d(TAG, "setScrollGesturesEnabledDuringRotateOrZoom: $scrollDuringZoom") + this.isScrollGesturesEnabledDuringRotateOrZoom = scrollDuringZoom + } + + override fun isScrollGesturesEnabledDuringRotateOrZoom(): Boolean { + Log.d(TAG, "isScrollGesturesEnabledDuringRotateOrZoom") + return isScrollGesturesEnabledDuringRotateOrZoom ?: true + } + + override fun setIndoorLevelPickerEnabled(indoorLevelPicker: Boolean) { + Log.d(TAG, "setIndoorLevelPickerEnabled: $indoorLevelPicker") + this.isIndoorLevelPickerEnabled = indoorLevelPicker + } + + override fun isIndoorLevelPickerEnabled(): Boolean { + Log.d(TAG, "isIndoorLevelPickerEnabled") + return isIndoorLevelPickerEnabled ?: true + } + + override fun setMyLocationButtonEnabled(locationButton: Boolean) { + Log.d(TAG, "setMyLocationButtonEnabled: $locationButton") + this.isMyLocationButtonEnabled = locationButton + } + + override fun isMyLocationButtonEnabled(): Boolean { + Log.d(TAG, "isMyLocationButtonEnabled") + return isMyLocationButtonEnabled ?: true + } + + override fun setZoomControlsEnabled(zoom: Boolean) { + Log.d(TAG, "setZoomControlsEnabled: $zoom") + this.isZoomControlsEnabled = zoom + } + + override fun isZoomControlsEnabled(): Boolean { + Log.d(TAG, "isZoomControlsEnabled") + return isZoomControlsEnabled ?: true + } + + override fun setCompassEnabled(compass: Boolean) { + this.compass = compass + } + + override fun setScrollGesturesEnabled(scrollGestures: Boolean) { + this.scrollGestures = scrollGestures + } + + override fun setZoomGesturesEnabled(zoomGestures: Boolean) { + this.zoomGestures = zoomGestures + } + + override fun setTiltGesturesEnabled(tiltGestures: Boolean) { + this.tiltGestures = tiltGestures + } + + override fun setRotateGesturesEnabled(rotateGestures: Boolean) { + this.rotateGestures = rotateGestures + } + + override fun setAllGesturesEnabled(gestures: Boolean) { + isAllGesturesEnabled = gestures + // Simulate MapLibre's UiSettings behavior + isScrollGesturesEnabled = gestures + isRotateGesturesEnabled = gestures + isTiltGesturesEnabled = gestures + isZoomGesturesEnabled = gestures + + // Other gestures toggles double tap and quick zoom gestures + otherGestures = gestures + } + + override fun isCompassEnabled(): Boolean { + return compass ?: true + } + + override fun isScrollGesturesEnabled(): Boolean { + return scrollGestures ?: true + } + + override fun isZoomGesturesEnabled(): Boolean { + return zoomGestures ?: true + } + + override fun isTiltGesturesEnabled(): Boolean { + return tiltGestures ?: true + } + + override fun isRotateGesturesEnabled(): Boolean { + return rotateGestures ?: true + } + + fun getMapReadyCallback(): OnMapReadyCallback = OnMapReadyCallback { map -> + val uiSettings = map.uiSettings + compass?.let { uiSettings.isCompassEnabled = it } + scrollGestures?.let { uiSettings.isScrollGesturesEnabled = it } + zoomGestures?.let { uiSettings.isZoomGesturesEnabled = it } + tiltGestures?.let { uiSettings.isTiltGesturesEnabled = it } + rotateGestures?.let { uiSettings.isRotateGesturesEnabled = it } + isAllGesturesEnabled?.let { uiSettings.setAllGesturesEnabled(it) } + + isZoomControlsEnabled?.let { uiSettings.isZoomControlsEnabled = it } + isMyLocationButtonEnabled?.let { uiSettings.isMyLocationButtonEnabled = it } + isIndoorLevelPickerEnabled?.let { uiSettings.isIndoorLevelPickerEnabled = it } + isMapToolbarEnabled?.let { uiSettings.isMapToolbarEnabled = it } + isScrollGesturesEnabledDuringRotateOrZoom?.let { uiSettings.isScrollGesturesEnabledDuringRotateOrZoom = it } } }