Skip to content

Commit

Permalink
Fix ITMGeolocationManager crash (#97)
Browse files Browse the repository at this point in the history
* Fix ITMGeolocationManager crash

* Use reentrantlock when accessing watchIds

* Match style

* Fix indentation
  • Loading branch information
ValdasSorys authored Oct 17, 2024
1 parent d8243fa commit d253475
Showing 1 changed file with 28 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import com.google.gson.Gson
import kotlinx.coroutines.*
import kotlinx.coroutines.tasks.await
import java.util.*
import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.schedule
import kotlin.math.*

Expand Down Expand Up @@ -78,9 +79,11 @@ class ITMGeolocationManager(private var context: Context, private val errorHandl

@JavascriptInterface
fun clearWatch(positionId: Int) {
watchIds.remove(positionId)
if (watchIds.isEmpty()) {
stopLocationUpdates()
getWatchIds {
it.remove(positionId)
if (it.isEmpty()) {
stopLocationUpdates()
}
}
}
}
Expand Down Expand Up @@ -223,7 +226,16 @@ class ITMGeolocationManager(private var context: Context, private val errorHandl
private var haveRotationReading = false
private var listening = false

private val watchIds: MutableSet<Int> = mutableSetOf()
private val watchIdsUnsafe: MutableSet<Int> = mutableSetOf()
private val getWatchIdsLock = ReentrantLock()
private fun <T>getWatchIds(callback: (MutableSet<Int>) -> T): T {
getWatchIdsLock.lock()
try {
return callback(watchIdsUnsafe)
} finally {
getWatchIdsLock.unlock()
}
}
private val watchLocationRequest by lazy { LocationRequest.Builder(1000).setPriority(Priority.PRIORITY_HIGH_ACCURACY).build() }
private var lastLocation: Location? = null
private val watchTimer = Timer("GeolocationWatch")
Expand Down Expand Up @@ -268,7 +280,7 @@ class ITMGeolocationManager(private var context: Context, private val errorHandl
}
}
val haveReading = haveAccelerometerReading && (haveMagneticReading || haveRotationReading || haveHeadingReading)
if (!haveReading || watchIds.isEmpty() || watchTimerTask != null) {
if (!haveReading || getWatchIds { it.isEmpty() } || watchTimerTask != null) {
return
}
// Only update heading a maximum of 10 times per second.
Expand Down Expand Up @@ -312,7 +324,7 @@ class ITMGeolocationManager(private var context: Context, private val errorHandl
mainScope.cancel()
cancellationTokenSource.cancel()
watchTimer.cancel()
if (watchIds.isNotEmpty()) {
if (getWatchIds { it.isNotEmpty() }) {
stopLocationUpdates()
}
}
Expand All @@ -329,7 +341,7 @@ class ITMGeolocationManager(private var context: Context, private val errorHandl
* Resume watches stopped by [stopLocationUpdates].
*/
fun resumeLocationUpdates() {
if (watchIds.isNotEmpty())
if (getWatchIds { it.isNotEmpty() })
requestLocationUpdates()
}
//endregion
Expand Down Expand Up @@ -381,9 +393,11 @@ class ITMGeolocationManager(private var context: Context, private val errorHandl
//region Position tracking
private suspend fun trackPosition(positionId: Int) {
ensureLocationAvailability()
watchIds.add(positionId)
if (watchIds.size == 1) {
requestLocationUpdates()
getWatchIds {
it.add(positionId)
if (it.size == 0) {
requestLocationUpdates()
}
}
}

Expand Down Expand Up @@ -583,8 +597,10 @@ class ITMGeolocationManager(private var context: Context, private val errorHandl
} else {
getAveragedHeading()
}
for (watchId in watchIds) {
sendPosition(location.toGeolocationPosition(heading), watchId, "watchPosition")
getWatchIds {
for (watchId in it) {
sendPosition(location.toGeolocationPosition(heading), watchId, "watchPosition")
}
}
}
}
Expand Down

0 comments on commit d253475

Please sign in to comment.