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

Commit bcded2c7 authored by Fynn Godau's avatar Fynn Godau Committed by Marvin W.
Browse files

Run user callbacks after `onCreate`

parent 70483632
Loading
Loading
Loading
Loading
+49 −27
Original line number Diff line number Diff line
@@ -88,7 +88,8 @@ class GoogleMapImpl(context: Context, var options: GoogleMapOptions) : AbstractG
    private var loaded = false
    private val mapLock = Object()

    private val initializedCallbackList = mutableListOf<OnMapReadyCallback>()
    private val internalOnInitializedCallbackList = mutableListOf<OnMapReadyCallback>()
    private val userOnInitializedCallbackList = mutableListOf<IOnMapReadyCallback>()
    private var loadedCallback: IOnMapLoadedCallback? = null
    private var cameraChangeListener: IOnCameraChangeListener? = null
    private var cameraMoveListener: IOnCameraMoveListener? = null
@@ -205,7 +206,7 @@ class GoogleMapImpl(context: Context, var options: GoogleMapOptions) : AbstractG
            if (initialized) {
                runnable(map!!)
            } else {
                initializedCallbackList.add(OnMapReadyCallback {
                internalOnInitializedCallbackList.add(OnMapReadyCallback {
                    runnable(it)
                })
            }
@@ -454,7 +455,7 @@ class GoogleMapImpl(context: Context, var options: GoogleMapOptions) : AbstractG
    override fun getUiSettings(): IUiSettingsDelegate =
        map?.uiSettings?.let { UiSettingsImpl(it) } ?: UiSettingsCache().also {
            // Apply cached UI settings after map is initialized
            initializedCallbackList.add(it.getMapReadyCallback())
            internalOnInitializedCallbackList.add(it.getMapReadyCallback())
        }

    override fun getProjection(): IProjectionDelegate = map?.projection?.let {
@@ -566,6 +567,7 @@ class GoogleMapImpl(context: Context, var options: GoogleMapOptions) : AbstractG
            mapView.onCreate(savedInstanceState?.toMapbox())
            mapView.getMapAsync(this::initMap)
            created = true
            runOnMainLooper(forceQueue = true) { tryRunUserInitializedCallbacks("onCreate") }
        }
    }

@@ -654,13 +656,16 @@ class GoogleMapImpl(context: Context, var options: GoogleMapOptions) : AbstractG
        synchronized(mapLock) {
            initialized = true
            waitingCameraUpdates.forEach { map.moveCamera(it) }
            val initializedCallbackList = ArrayList(initializedCallbackList)
            Log.d(TAG, "Invoking ${initializedCallbackList.size} callbacks delayed, as map is initialized")
            val initializedCallbackList = ArrayList(internalOnInitializedCallbackList)
            Log.d(TAG, "Invoking ${initializedCallbackList.size} internal callbacks now that the true map is initialized")
            for (callback in initializedCallbackList) {
                callback.onMapReady(map)
            }
        }

        // No effect if no initialized callbacks are present.
        tryRunUserInitializedCallbacks(tag = "initMap")

        map.getStyle {
            mapView?.let { view ->
                if (loaded) return@let
@@ -842,18 +847,36 @@ class GoogleMapImpl(context: Context, var options: GoogleMapOptions) : AbstractG

    fun getMapAsync(callback: IOnMapReadyCallback) {
        synchronized(mapLock) {
            userOnInitializedCallbackList.add(callback)
        }
        tryRunUserInitializedCallbacks("getMapAsync")
    }

    fun tryRunUserInitializedCallbacks(tag: String = "") {

        synchronized(mapLock) {
            if (userOnInitializedCallbackList.isEmpty()) return
        }

            val runCallback = {
        val runCallbacks = {
            synchronized(mapLock) {
                userOnInitializedCallbackList.forEach {
                    try {
                    callback.onMapReady(this)
                        it.onMapReady(this)
                    } catch (e: Exception) {
                        Log.w(TAG, e)
                    }
                }.also {
                    userOnInitializedCallbackList.clear()
                }
            }
        }

            if (initialized) {
                Log.d(TAG, "Invoking callback instantly, as map is initialized")
                runCallback()
        val map = map
        if (initialized && map != null) {
            // Call all callbacks immediately, as map is ready
            Log.d("$TAG:$tag", "Invoking callback instantly, as map is initialized")
            runCallbacks()
        } else if (mapView?.isShown == false) {
            /* If map is hidden, an app (e.g. Dott) may expect it to initialize anyway and
             * will not show the map until it is initialized. However, we should not call
@@ -862,13 +885,12 @@ class GoogleMapImpl(context: Context, var options: GoogleMapOptions) : AbstractG
             * initializing).
             */
            runOnMainLooper(forceQueue = true) {
                    Log.d(TAG, "Invoking callback now: map cannot be initialized because it is not shown (yet)")
                    runCallback()
                Log.d("$TAG:$tag", "Invoking callback now: map cannot be initialized because it is not shown (yet)")
                runCallbacks()
            }
        } else {
                Log.d(TAG, "Delay callback invocation, as map is not yet initialized")
                initializedCallbackList.add { runCallback() }
            }
            Log.d("$TAG:$tag", "Initialized callbacks could not be run at this point, as the map view has not been created yet.")
            // Will be retried after initialization.
        }
    }