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

Commit 74bff5ec authored by Fynn Godau's avatar Fynn Godau
Browse files

Invoke map initialized callback prematurely if needed

parent 4bdbc20f
Loading
Loading
Loading
Loading
+72 −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,7 @@ 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.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 +88,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
@@ -167,7 +170,8 @@ 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

@@ -193,15 +197,18 @@ 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) {
                assert(map != null)
                runnable(map!!)
            } else {
                initializedCallbackList.add(OnMapReadyCallback {
                    runnable(it)
                })
            }
        }
    }

    override fun animateCameraWithCallback(cameraUpdate: IObjectWrapper?, callback: ICancelableCallback?) {
        val update = cameraUpdate.unwrap<CameraUpdate>() ?: return
@@ -210,7 +217,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() }
            }
        }
    }
@@ -222,7 +229,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() }
            }
        }
    }
@@ -234,21 +241,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? {
@@ -366,8 +373,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 {
@@ -424,7 +431,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 {
@@ -433,6 +444,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?) {
@@ -485,18 +511,16 @@ 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 {
        Log.d(TAG, "setPadding: $left $top $right $bottom")
        map?.let { map ->
            map.setPadding(left, top, right, bottom)
        it.setPadding(left, top, right, bottom)
        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()
                ?: 0
            map.uiSettings.setLogoMargins(left + fourDp, top + fourDp, right + fourDp, bottom + fourDp)
            map.uiSettings.setCompassMargins(left + fourDp, top + fourDp, right + fourDp, bottom + fourDp)
            map.uiSettings.setAttributionMargins(left + ninetyTwoDp, top + fourDp, right + fourDp, bottom + fourDp)
        }
        it.uiSettings.setLogoMargins(left + fourDp, top + fourDp, right + fourDp, bottom + fourDp)
        it.uiSettings.setCompassMargins(left + fourDp, top + fourDp, right + fourDp, bottom + fourDp)
        it.uiSettings.setAttributionMargins(left + ninetyTwoDp, top + fourDp, right + fourDp, bottom + fourDp)
    }

    override fun isBuildingsEnabled(): Boolean {
@@ -506,7 +530,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?) {
@@ -636,11 +659,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)
            }
        }

@@ -766,8 +785,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
@@ -799,16 +817,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() }
            }
        }
    }
+123 −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,81 @@ 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

        //setDoubleTapGesturesEnabled(gestures)
        //setQuickZoomGesturesEnabled(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