Loading play-services-maps-core-mapbox/build.gradle +3 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,9 @@ def execResult(...args) { } def mapboxKey() { String environmentKey = System.getenv('MAPBOX_VECTOR_TILES_KEY') if (environmentKey != null) return environmentKey Properties properties = new Properties() try { properties.load(project.rootProject.file('local.properties').newDataInputStream()) Loading play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/CameraBoundsWithSizeUpdate.kt +25 −8 Original line number Diff line number Diff line Loading @@ -29,14 +29,31 @@ internal class CameraBoundsWithSizeUpdate(val bounds: LatLngBounds, val width: I override fun getCameraPosition(map: MapboxMap): CameraPosition? { val padding = this.padding.clone() val widthPad = ((map.width + map.padding[0] + map.padding[2] - width) / 2).toInt() val heightPad = ((map.height + map.padding[1] + map.padding[3] - height) / 2).toInt() padding[0] += widthPad padding[1] += heightPad padding[2] += widthPad padding[3] += heightPad Log.d(TAG, "map ${map.width} ${map.height}, set $width $height -> ${padding.map { it.toString() }.reduce { a, b -> "$a,$b"}}") return map.getCameraForLatLngBounds(bounds, padding) val mapPadding = map.cameraPosition.padding mapPadding?.let { for (i in 0..3) { padding[i] += it[i].toInt() } } val widthPadding = ((map.width - width) / 2).toInt() val heightPadding = ((map.height - height) / 2).toInt() padding[0] += widthPadding padding[1] += heightPadding padding[2] += widthPadding padding[3] += heightPadding Log.d(TAG, "map ${map.width} ${map.height}, set $width $height -> ${Arrays.toString(padding)}") return map.getCameraForLatLngBounds(bounds, padding)?.let { CameraPosition.Builder(it) .apply { mapPadding?.let { padding(it) } }.build() } } override fun equals(other: Any?): Boolean { Loading play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +75 −45 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package org.microg.gms.maps.mapbox import android.annotation.SuppressLint import android.content.Context import android.graphics.Point import android.location.Location import android.os.* import androidx.annotation.IdRes Loading @@ -30,6 +31,7 @@ import android.widget.FrameLayout import android.widget.RelativeLayout import androidx.collection.LongSparseArray import com.google.android.gms.dynamic.IObjectWrapper import com.google.android.gms.dynamic.ObjectWrapper import com.google.android.gms.maps.GoogleMapOptions import com.google.android.gms.maps.internal.* import com.google.android.gms.maps.model.* Loading @@ -52,6 +54,8 @@ import com.mapbox.mapboxsdk.plugins.annotation.Annotation import com.mapbox.mapboxsdk.style.layers.Property.LINE_CAP_ROUND import com.google.android.gms.dynamic.unwrap import com.mapbox.mapboxsdk.WellKnownTileServer import com.mapbox.mapboxsdk.camera.CameraUpdateFactory import com.mapbox.mapboxsdk.maps.OnMapReadyCallback import org.microg.gms.maps.MapsConstants.* import org.microg.gms.maps.mapbox.model.* import org.microg.gms.maps.mapbox.utils.MapContext Loading Loading @@ -85,7 +89,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) private var loaded = false private val mapLock = Object() private val initializedCallbackList = mutableListOf<IOnMapReadyCallback>() private val initializedCallbackList = mutableListOf<OnMapReadyCallback>() private var loadedCallback: IOnMapLoadedCallback? = null private var cameraChangeListener: IOnCameraChangeListener? = null private var cameraMoveListener: IOnCameraMoveListener? = null Loading Loading @@ -165,7 +169,9 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } } override fun getCameraPosition(): CameraPosition? = map?.cameraPosition?.toGms() override fun getCameraPosition(): CameraPosition = map?.cameraPosition?.toGms() ?: CameraPosition(LatLng(0.0, 0.0), 0f, 0f, 0f) override fun getMaxZoomLevel(): Float = (map?.maxZoomLevel?.toFloat() ?: 20f) + 1f override fun getMinZoomLevel(): Float = (map?.minZoomLevel?.toFloat() ?: 0f) + 1f Loading @@ -191,15 +197,17 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } } fun afterInitialized(runnable: () -> Unit) { initializedCallbackList.add(object : IOnMapReadyCallback { override fun onMapReady(map: IGoogleMapDelegate?) { runnable() } override fun asBinder(): IBinder? = null fun afterInitialize(runnable: (MapboxMap) -> Unit) { synchronized(mapLock) { if (initialized) { runnable(map!!) } else { initializedCallbackList.add(OnMapReadyCallback { runnable(it) }) } } } override fun animateCameraWithCallback(cameraUpdate: IObjectWrapper?, callback: ICancelableCallback?) { val update = cameraUpdate.unwrap<CameraUpdate>() ?: return Loading @@ -208,7 +216,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) this.map?.animateCamera(update, callback?.toMapbox()) } else { waitingCameraUpdates.add(update) afterInitialized { callback?.onFinish() } afterInitialize { callback?.onFinish() } } } } Loading @@ -220,7 +228,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) this.map?.animateCamera(update, duration, callback?.toMapbox()) } else { waitingCameraUpdates.add(update) afterInitialized { callback?.onFinish() } afterInitialize { callback?.onFinish() } } } } Loading @@ -232,21 +240,21 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) return true } override fun setMinZoomPreference(minZoom: Float) { map?.setMinZoomPreference(minZoom.toDouble() - 1) override fun setMinZoomPreference(minZoom: Float) = afterInitialize { it.setMinZoomPreference(minZoom.toDouble() - 1) } override fun setMaxZoomPreference(maxZoom: Float) { map?.setMaxZoomPreference(maxZoom.toDouble() - 1) override fun setMaxZoomPreference(maxZoom: Float) = afterInitialize { it.setMaxZoomPreference(maxZoom.toDouble() - 1) } override fun resetMinMaxZoomPreference() { map?.setMinZoomPreference(MapboxConstants.MINIMUM_ZOOM.toDouble()) map?.setMaxZoomPreference(MapboxConstants.MAXIMUM_ZOOM.toDouble()) override fun resetMinMaxZoomPreference() = afterInitialize { it.setMinZoomPreference(MapboxConstants.MINIMUM_ZOOM.toDouble()) it.setMaxZoomPreference(MapboxConstants.MAXIMUM_ZOOM.toDouble()) } override fun setLatLngBoundsForCameraTarget(bounds: LatLngBounds?) { map?.setLatLngBoundsForCameraTarget(bounds?.toMapbox()) override fun setLatLngBoundsForCameraTarget(bounds: LatLngBounds?) = afterInitialize { it.setLatLngBoundsForCameraTarget(bounds?.toMapbox()) } override fun addPolyline(options: PolylineOptions): IPolylineDelegate? { Loading Loading @@ -367,8 +375,8 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } override fun setWatermarkEnabled(watermark: Boolean) { map?.uiSettings?.isLogoEnabled = watermark override fun setWatermarkEnabled(watermark: Boolean) = afterInitialize { it.uiSettings.isLogoEnabled = watermark } override fun isTrafficEnabled(): Boolean { Loading Loading @@ -425,7 +433,11 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) mapView?.contentDescription = desc } override fun getUiSettings(): IUiSettingsDelegate? = map?.uiSettings?.let { UiSettingsImpl(it) } override fun getUiSettings(): IUiSettingsDelegate = map?.uiSettings?.let { UiSettingsImpl(it) } ?: UiSettingsCache().also { // Apply cached UI settings after map is initialized initializedCallbackList.add(it.getMapReadyCallback()) } override fun getProjection(): IProjectionDelegate? = map?.projection?.let { val experiment = try { Loading @@ -434,6 +446,21 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) Log.w(TAG, e); false } ProjectionImpl(it, experiment) } ?: object : IProjectionDelegate.Stub() { // dummy projection if map not initialized 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))) } } override fun setOnCameraChangeListener(listener: IOnCameraChangeListener?) { Loading Loading @@ -490,10 +517,11 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) { override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) = afterInitialize { map -> Log.d(TAG, "setPadding: $left $top $right $bottom") map?.let { map -> map.setPadding(left, top, right, bottom) CameraUpdateFactory.paddingTo(left.toDouble(), top.toDouble(), right.toDouble(), bottom.toDouble()) .let { map.moveCamera(it) } val fourDp = mapView?.context?.resources?.getDimension(R.dimen.mapbox_four_dp)?.toInt() ?: 0 val ninetyTwoDp = mapView?.context?.resources?.getDimension(R.dimen.mapbox_ninety_two_dp)?.toInt() Loading @@ -502,7 +530,6 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) map.uiSettings.setCompassMargins(left + fourDp, top + fourDp, right + fourDp, bottom + fourDp) map.uiSettings.setAttributionMargins(left + ninetyTwoDp, top + fourDp, right + fourDp, bottom + fourDp) } } override fun isBuildingsEnabled(): Boolean { Log.d(TAG, "unimplemented Method: isBuildingsEnabled") Loading @@ -511,7 +538,6 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) override fun setBuildingsEnabled(buildings: Boolean) { Log.d(TAG, "unimplemented Method: setBuildingsEnabled") } override fun setOnMapLoadedCallback(callback: IOnMapLoadedCallback?) { Loading Loading @@ -641,11 +667,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) val initializedCallbackList = ArrayList(initializedCallbackList) Log.d(TAG, "Invoking ${initializedCallbackList.size} callbacks delayed, as map is initialized") for (callback in initializedCallbackList) { try { callback.onMapReady(this) } catch (e: Exception) { Log.w(TAG, e) } callback.onMapReady(map) } } Loading Loading @@ -782,8 +804,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) mapView?.onDestroy() mapView = null // Don't make it null; this object is not deleted immediately, and it may want to access map.* stuff //map = null map = null created = false initialized = false Loading Loading @@ -815,16 +836,25 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) fun getMapAsync(callback: IOnMapReadyCallback) { synchronized(mapLock) { if (initialized) { Log.d(TAG, "Invoking callback instantly, as map is initialized") val runCallback = { try { callback.onMapReady(this) } catch (e: Exception) { Log.w(TAG, e) } } if (initialized) { Log.d(TAG, "Invoking callback instantly, as map is initialized") runCallback() } else if (mapView?.isShown != true) { // If map is not shown, an app (e.g. Dott) may expect it to initialize anyway – before showing it Log.d(TAG, "Invoking callback instantly: map cannot be initialized because it is not shown (yet)") runCallback() } else { Log.d(TAG, "Delay callback invocation, as map is not yet initialized") initializedCallbackList.add(callback) initializedCallbackList.add { runCallback() } } } } Loading play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Projection.kt +1 −1 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ import kotlin.math.roundToInt // TODO: Do calculations using backed up locations instead of live (which requires UI thread) class ProjectionImpl(private val projection: Projection, private val withoutTiltOrBearing: Boolean) : IProjectionDelegate.Stub() { private val visibleRegion = projection.visibleRegion private val visibleRegion = projection.getVisibleRegion(false) private val farLeft = projection.toScreenLocation(visibleRegion.farLeft) private val farRight = projection.toScreenLocation(visibleRegion.farRight) private val nearLeft = projection.toScreenLocation(visibleRegion.nearLeft) Loading play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/UiSettings.kt +122 −39 Original line number Diff line number Diff line Loading @@ -17,45 +17,22 @@ package org.microg.gms.maps.mapbox import android.os.Parcel import android.os.RemoteException import android.util.Log import com.google.android.gms.maps.internal.IUiSettingsDelegate import com.mapbox.mapboxsdk.maps.OnMapReadyCallback import com.mapbox.mapboxsdk.maps.UiSettings class UiSettingsImpl(private val uiSettings: UiSettings) : IUiSettingsDelegate.Stub() { /** * 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 setCompassEnabled(compass: Boolean) { uiSettings.isCompassEnabled = compass } override fun setMyLocationButtonEnabled(locationButton: Boolean) { Log.d(TAG, "unimplemented Method: setMyLocationButtonEnabled") } override fun setScrollGesturesEnabled(scrollGestures: Boolean) { uiSettings.isScrollGesturesEnabled = scrollGestures } override fun setZoomGesturesEnabled(zoomGestures: Boolean) { uiSettings.isZoomGesturesEnabled = zoomGestures } override fun setTiltGesturesEnabled(tiltGestures: Boolean) { uiSettings.isTiltGesturesEnabled = tiltGestures } override fun setRotateGesturesEnabled(rotateGestures: Boolean) { uiSettings.isRotateGesturesEnabled = rotateGestures } override fun setAllGesturesEnabled(gestures: Boolean) { uiSettings.setAllGesturesEnabled(gestures) } override fun isZoomControlsEnabled(): Boolean { Loading @@ -63,21 +40,11 @@ class UiSettingsImpl(private val uiSettings: UiSettings) : IUiSettingsDelegate.S return false } override fun isCompassEnabled(): Boolean = uiSettings.isCompassEnabled override fun isMyLocationButtonEnabled(): Boolean { Log.d(TAG, "unimplemented Method: isMyLocationButtonEnabled") return false } override fun isScrollGesturesEnabled(): Boolean = uiSettings.isScrollGesturesEnabled override fun isZoomGesturesEnabled(): Boolean = uiSettings.isZoomGesturesEnabled override fun isTiltGesturesEnabled(): Boolean = uiSettings.isTiltGesturesEnabled override fun isRotateGesturesEnabled(): Boolean = uiSettings.isRotateGesturesEnabled override fun setIndoorLevelPickerEnabled(indoorLevelPicker: Boolean) { Log.d(TAG, "unimplemented Method: setIndoorLevelPickerEnabled") } Loading Loading @@ -105,6 +72,48 @@ class UiSettingsImpl(private val uiSettings: UiSettings) : IUiSettingsDelegate.S return true } companion object { private val TAG = "GmsMapsUi" } } class UiSettingsImpl(private val uiSettings: UiSettings) : AbstractUiSettings() { override fun setCompassEnabled(compass: Boolean) { uiSettings.isCompassEnabled = compass } override fun setScrollGesturesEnabled(scrollGestures: Boolean) { uiSettings.isScrollGesturesEnabled = scrollGestures } override fun setZoomGesturesEnabled(zoomGestures: Boolean) { uiSettings.isZoomGesturesEnabled = zoomGestures } override fun setTiltGesturesEnabled(tiltGestures: Boolean) { uiSettings.isTiltGesturesEnabled = tiltGestures } override fun setRotateGesturesEnabled(rotateGestures: Boolean) { uiSettings.isRotateGesturesEnabled = rotateGestures } override fun setAllGesturesEnabled(gestures: Boolean) { uiSettings.setAllGesturesEnabled(gestures) } override fun isCompassEnabled(): Boolean = uiSettings.isCompassEnabled override fun isScrollGesturesEnabled(): Boolean = uiSettings.isScrollGesturesEnabled override fun isZoomGesturesEnabled(): Boolean = uiSettings.isZoomGesturesEnabled override fun isTiltGesturesEnabled(): Boolean = uiSettings.isTiltGesturesEnabled override fun isRotateGesturesEnabled(): Boolean = uiSettings.isRotateGesturesEnabled override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean = if (super.onTransact(code, data, reply, flags)) { true Loading @@ -113,6 +122,80 @@ class UiSettingsImpl(private val uiSettings: UiSettings) : IUiSettingsDelegate.S } companion object { private val TAG = "GmsMapsUi" private val TAG = "GmsMapsUiImpl" } } 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 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) { // 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 } otherGestures?.let { uiSettings.isDoubleTapGesturesEnabled = it uiSettings.isQuickZoomGesturesEnabled = it } } } No newline at end of file Loading
play-services-maps-core-mapbox/build.gradle +3 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,9 @@ def execResult(...args) { } def mapboxKey() { String environmentKey = System.getenv('MAPBOX_VECTOR_TILES_KEY') if (environmentKey != null) return environmentKey Properties properties = new Properties() try { properties.load(project.rootProject.file('local.properties').newDataInputStream()) Loading
play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/CameraBoundsWithSizeUpdate.kt +25 −8 Original line number Diff line number Diff line Loading @@ -29,14 +29,31 @@ internal class CameraBoundsWithSizeUpdate(val bounds: LatLngBounds, val width: I override fun getCameraPosition(map: MapboxMap): CameraPosition? { val padding = this.padding.clone() val widthPad = ((map.width + map.padding[0] + map.padding[2] - width) / 2).toInt() val heightPad = ((map.height + map.padding[1] + map.padding[3] - height) / 2).toInt() padding[0] += widthPad padding[1] += heightPad padding[2] += widthPad padding[3] += heightPad Log.d(TAG, "map ${map.width} ${map.height}, set $width $height -> ${padding.map { it.toString() }.reduce { a, b -> "$a,$b"}}") return map.getCameraForLatLngBounds(bounds, padding) val mapPadding = map.cameraPosition.padding mapPadding?.let { for (i in 0..3) { padding[i] += it[i].toInt() } } val widthPadding = ((map.width - width) / 2).toInt() val heightPadding = ((map.height - height) / 2).toInt() padding[0] += widthPadding padding[1] += heightPadding padding[2] += widthPadding padding[3] += heightPadding Log.d(TAG, "map ${map.width} ${map.height}, set $width $height -> ${Arrays.toString(padding)}") return map.getCameraForLatLngBounds(bounds, padding)?.let { CameraPosition.Builder(it) .apply { mapPadding?.let { padding(it) } }.build() } } override fun equals(other: Any?): Boolean { Loading
play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +75 −45 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package org.microg.gms.maps.mapbox import android.annotation.SuppressLint import android.content.Context import android.graphics.Point import android.location.Location import android.os.* import androidx.annotation.IdRes Loading @@ -30,6 +31,7 @@ import android.widget.FrameLayout import android.widget.RelativeLayout import androidx.collection.LongSparseArray import com.google.android.gms.dynamic.IObjectWrapper import com.google.android.gms.dynamic.ObjectWrapper import com.google.android.gms.maps.GoogleMapOptions import com.google.android.gms.maps.internal.* import com.google.android.gms.maps.model.* Loading @@ -52,6 +54,8 @@ import com.mapbox.mapboxsdk.plugins.annotation.Annotation import com.mapbox.mapboxsdk.style.layers.Property.LINE_CAP_ROUND import com.google.android.gms.dynamic.unwrap import com.mapbox.mapboxsdk.WellKnownTileServer import com.mapbox.mapboxsdk.camera.CameraUpdateFactory import com.mapbox.mapboxsdk.maps.OnMapReadyCallback import org.microg.gms.maps.MapsConstants.* import org.microg.gms.maps.mapbox.model.* import org.microg.gms.maps.mapbox.utils.MapContext Loading Loading @@ -85,7 +89,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) private var loaded = false private val mapLock = Object() private val initializedCallbackList = mutableListOf<IOnMapReadyCallback>() private val initializedCallbackList = mutableListOf<OnMapReadyCallback>() private var loadedCallback: IOnMapLoadedCallback? = null private var cameraChangeListener: IOnCameraChangeListener? = null private var cameraMoveListener: IOnCameraMoveListener? = null Loading Loading @@ -165,7 +169,9 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } } override fun getCameraPosition(): CameraPosition? = map?.cameraPosition?.toGms() override fun getCameraPosition(): CameraPosition = map?.cameraPosition?.toGms() ?: CameraPosition(LatLng(0.0, 0.0), 0f, 0f, 0f) override fun getMaxZoomLevel(): Float = (map?.maxZoomLevel?.toFloat() ?: 20f) + 1f override fun getMinZoomLevel(): Float = (map?.minZoomLevel?.toFloat() ?: 0f) + 1f Loading @@ -191,15 +197,17 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } } fun afterInitialized(runnable: () -> Unit) { initializedCallbackList.add(object : IOnMapReadyCallback { override fun onMapReady(map: IGoogleMapDelegate?) { runnable() } override fun asBinder(): IBinder? = null fun afterInitialize(runnable: (MapboxMap) -> Unit) { synchronized(mapLock) { if (initialized) { runnable(map!!) } else { initializedCallbackList.add(OnMapReadyCallback { runnable(it) }) } } } override fun animateCameraWithCallback(cameraUpdate: IObjectWrapper?, callback: ICancelableCallback?) { val update = cameraUpdate.unwrap<CameraUpdate>() ?: return Loading @@ -208,7 +216,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) this.map?.animateCamera(update, callback?.toMapbox()) } else { waitingCameraUpdates.add(update) afterInitialized { callback?.onFinish() } afterInitialize { callback?.onFinish() } } } } Loading @@ -220,7 +228,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) this.map?.animateCamera(update, duration, callback?.toMapbox()) } else { waitingCameraUpdates.add(update) afterInitialized { callback?.onFinish() } afterInitialize { callback?.onFinish() } } } } Loading @@ -232,21 +240,21 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) return true } override fun setMinZoomPreference(minZoom: Float) { map?.setMinZoomPreference(minZoom.toDouble() - 1) override fun setMinZoomPreference(minZoom: Float) = afterInitialize { it.setMinZoomPreference(minZoom.toDouble() - 1) } override fun setMaxZoomPreference(maxZoom: Float) { map?.setMaxZoomPreference(maxZoom.toDouble() - 1) override fun setMaxZoomPreference(maxZoom: Float) = afterInitialize { it.setMaxZoomPreference(maxZoom.toDouble() - 1) } override fun resetMinMaxZoomPreference() { map?.setMinZoomPreference(MapboxConstants.MINIMUM_ZOOM.toDouble()) map?.setMaxZoomPreference(MapboxConstants.MAXIMUM_ZOOM.toDouble()) override fun resetMinMaxZoomPreference() = afterInitialize { it.setMinZoomPreference(MapboxConstants.MINIMUM_ZOOM.toDouble()) it.setMaxZoomPreference(MapboxConstants.MAXIMUM_ZOOM.toDouble()) } override fun setLatLngBoundsForCameraTarget(bounds: LatLngBounds?) { map?.setLatLngBoundsForCameraTarget(bounds?.toMapbox()) override fun setLatLngBoundsForCameraTarget(bounds: LatLngBounds?) = afterInitialize { it.setLatLngBoundsForCameraTarget(bounds?.toMapbox()) } override fun addPolyline(options: PolylineOptions): IPolylineDelegate? { Loading Loading @@ -367,8 +375,8 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } override fun setWatermarkEnabled(watermark: Boolean) { map?.uiSettings?.isLogoEnabled = watermark override fun setWatermarkEnabled(watermark: Boolean) = afterInitialize { it.uiSettings.isLogoEnabled = watermark } override fun isTrafficEnabled(): Boolean { Loading Loading @@ -425,7 +433,11 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) mapView?.contentDescription = desc } override fun getUiSettings(): IUiSettingsDelegate? = map?.uiSettings?.let { UiSettingsImpl(it) } override fun getUiSettings(): IUiSettingsDelegate = map?.uiSettings?.let { UiSettingsImpl(it) } ?: UiSettingsCache().also { // Apply cached UI settings after map is initialized initializedCallbackList.add(it.getMapReadyCallback()) } override fun getProjection(): IProjectionDelegate? = map?.projection?.let { val experiment = try { Loading @@ -434,6 +446,21 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) Log.w(TAG, e); false } ProjectionImpl(it, experiment) } ?: object : IProjectionDelegate.Stub() { // dummy projection if map not initialized 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))) } } override fun setOnCameraChangeListener(listener: IOnCameraChangeListener?) { Loading Loading @@ -490,10 +517,11 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) { override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) = afterInitialize { map -> Log.d(TAG, "setPadding: $left $top $right $bottom") map?.let { map -> map.setPadding(left, top, right, bottom) CameraUpdateFactory.paddingTo(left.toDouble(), top.toDouble(), right.toDouble(), bottom.toDouble()) .let { map.moveCamera(it) } val fourDp = mapView?.context?.resources?.getDimension(R.dimen.mapbox_four_dp)?.toInt() ?: 0 val ninetyTwoDp = mapView?.context?.resources?.getDimension(R.dimen.mapbox_ninety_two_dp)?.toInt() Loading @@ -502,7 +530,6 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) map.uiSettings.setCompassMargins(left + fourDp, top + fourDp, right + fourDp, bottom + fourDp) map.uiSettings.setAttributionMargins(left + ninetyTwoDp, top + fourDp, right + fourDp, bottom + fourDp) } } override fun isBuildingsEnabled(): Boolean { Log.d(TAG, "unimplemented Method: isBuildingsEnabled") Loading @@ -511,7 +538,6 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) override fun setBuildingsEnabled(buildings: Boolean) { Log.d(TAG, "unimplemented Method: setBuildingsEnabled") } override fun setOnMapLoadedCallback(callback: IOnMapLoadedCallback?) { Loading Loading @@ -641,11 +667,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) val initializedCallbackList = ArrayList(initializedCallbackList) Log.d(TAG, "Invoking ${initializedCallbackList.size} callbacks delayed, as map is initialized") for (callback in initializedCallbackList) { try { callback.onMapReady(this) } catch (e: Exception) { Log.w(TAG, e) } callback.onMapReady(map) } } Loading Loading @@ -782,8 +804,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) mapView?.onDestroy() mapView = null // Don't make it null; this object is not deleted immediately, and it may want to access map.* stuff //map = null map = null created = false initialized = false Loading Loading @@ -815,16 +836,25 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) fun getMapAsync(callback: IOnMapReadyCallback) { synchronized(mapLock) { if (initialized) { Log.d(TAG, "Invoking callback instantly, as map is initialized") val runCallback = { try { callback.onMapReady(this) } catch (e: Exception) { Log.w(TAG, e) } } if (initialized) { Log.d(TAG, "Invoking callback instantly, as map is initialized") runCallback() } else if (mapView?.isShown != true) { // If map is not shown, an app (e.g. Dott) may expect it to initialize anyway – before showing it Log.d(TAG, "Invoking callback instantly: map cannot be initialized because it is not shown (yet)") runCallback() } else { Log.d(TAG, "Delay callback invocation, as map is not yet initialized") initializedCallbackList.add(callback) initializedCallbackList.add { runCallback() } } } } Loading
play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/Projection.kt +1 −1 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ import kotlin.math.roundToInt // TODO: Do calculations using backed up locations instead of live (which requires UI thread) class ProjectionImpl(private val projection: Projection, private val withoutTiltOrBearing: Boolean) : IProjectionDelegate.Stub() { private val visibleRegion = projection.visibleRegion private val visibleRegion = projection.getVisibleRegion(false) private val farLeft = projection.toScreenLocation(visibleRegion.farLeft) private val farRight = projection.toScreenLocation(visibleRegion.farRight) private val nearLeft = projection.toScreenLocation(visibleRegion.nearLeft) Loading
play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/UiSettings.kt +122 −39 Original line number Diff line number Diff line Loading @@ -17,45 +17,22 @@ package org.microg.gms.maps.mapbox import android.os.Parcel import android.os.RemoteException import android.util.Log import com.google.android.gms.maps.internal.IUiSettingsDelegate import com.mapbox.mapboxsdk.maps.OnMapReadyCallback import com.mapbox.mapboxsdk.maps.UiSettings class UiSettingsImpl(private val uiSettings: UiSettings) : IUiSettingsDelegate.Stub() { /** * 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 setCompassEnabled(compass: Boolean) { uiSettings.isCompassEnabled = compass } override fun setMyLocationButtonEnabled(locationButton: Boolean) { Log.d(TAG, "unimplemented Method: setMyLocationButtonEnabled") } override fun setScrollGesturesEnabled(scrollGestures: Boolean) { uiSettings.isScrollGesturesEnabled = scrollGestures } override fun setZoomGesturesEnabled(zoomGestures: Boolean) { uiSettings.isZoomGesturesEnabled = zoomGestures } override fun setTiltGesturesEnabled(tiltGestures: Boolean) { uiSettings.isTiltGesturesEnabled = tiltGestures } override fun setRotateGesturesEnabled(rotateGestures: Boolean) { uiSettings.isRotateGesturesEnabled = rotateGestures } override fun setAllGesturesEnabled(gestures: Boolean) { uiSettings.setAllGesturesEnabled(gestures) } override fun isZoomControlsEnabled(): Boolean { Loading @@ -63,21 +40,11 @@ class UiSettingsImpl(private val uiSettings: UiSettings) : IUiSettingsDelegate.S return false } override fun isCompassEnabled(): Boolean = uiSettings.isCompassEnabled override fun isMyLocationButtonEnabled(): Boolean { Log.d(TAG, "unimplemented Method: isMyLocationButtonEnabled") return false } override fun isScrollGesturesEnabled(): Boolean = uiSettings.isScrollGesturesEnabled override fun isZoomGesturesEnabled(): Boolean = uiSettings.isZoomGesturesEnabled override fun isTiltGesturesEnabled(): Boolean = uiSettings.isTiltGesturesEnabled override fun isRotateGesturesEnabled(): Boolean = uiSettings.isRotateGesturesEnabled override fun setIndoorLevelPickerEnabled(indoorLevelPicker: Boolean) { Log.d(TAG, "unimplemented Method: setIndoorLevelPickerEnabled") } Loading Loading @@ -105,6 +72,48 @@ class UiSettingsImpl(private val uiSettings: UiSettings) : IUiSettingsDelegate.S return true } companion object { private val TAG = "GmsMapsUi" } } class UiSettingsImpl(private val uiSettings: UiSettings) : AbstractUiSettings() { override fun setCompassEnabled(compass: Boolean) { uiSettings.isCompassEnabled = compass } override fun setScrollGesturesEnabled(scrollGestures: Boolean) { uiSettings.isScrollGesturesEnabled = scrollGestures } override fun setZoomGesturesEnabled(zoomGestures: Boolean) { uiSettings.isZoomGesturesEnabled = zoomGestures } override fun setTiltGesturesEnabled(tiltGestures: Boolean) { uiSettings.isTiltGesturesEnabled = tiltGestures } override fun setRotateGesturesEnabled(rotateGestures: Boolean) { uiSettings.isRotateGesturesEnabled = rotateGestures } override fun setAllGesturesEnabled(gestures: Boolean) { uiSettings.setAllGesturesEnabled(gestures) } override fun isCompassEnabled(): Boolean = uiSettings.isCompassEnabled override fun isScrollGesturesEnabled(): Boolean = uiSettings.isScrollGesturesEnabled override fun isZoomGesturesEnabled(): Boolean = uiSettings.isZoomGesturesEnabled override fun isTiltGesturesEnabled(): Boolean = uiSettings.isTiltGesturesEnabled override fun isRotateGesturesEnabled(): Boolean = uiSettings.isRotateGesturesEnabled override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean = if (super.onTransact(code, data, reply, flags)) { true Loading @@ -113,6 +122,80 @@ class UiSettingsImpl(private val uiSettings: UiSettings) : IUiSettingsDelegate.S } companion object { private val TAG = "GmsMapsUi" private val TAG = "GmsMapsUiImpl" } } 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 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) { // 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 } otherGestures?.let { uiSettings.isDoubleTapGesturesEnabled = it uiSettings.isQuickZoomGesturesEnabled = it } } } No newline at end of file