Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 98dfdb03 authored by Fynn Godau's avatar Fynn Godau
Browse files

Merge branch 'epic67-maps' into 913-circles

parents 2e624ae9 7bb43c2e
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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())
+25 −8
Original line number Diff line number Diff line
@@ -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 {
+75 −45
Original line number Diff line number Diff line
@@ -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
@@ -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.*
@@ -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
@@ -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
@@ -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

@@ -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
@@ -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() }
            }
        }
    }
@@ -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() }
            }
        }
    }
@@ -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? {
@@ -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 {
@@ -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 {
@@ -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?) {
@@ -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()
@@ -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")
@@ -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?) {
@@ -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)
            }
        }

@@ -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
@@ -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() }
            }
        }
    }
+1 −1
Original line number Diff line number Diff line
@@ -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)
+122 −39
Original line number Diff line number Diff line
@@ -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 {
@@ -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")
    }
@@ -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
@@ -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