react-native-nitro-geolocation 1.2.5 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/README.md +55 -278
  2. package/android/build.gradle +1 -0
  3. package/android/src/main/AndroidManifest.xml +39 -0
  4. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidFusedLocationProvider.kt +310 -0
  5. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidFusedRequestFactory.kt +31 -0
  6. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidGeolocationConversions.kt +71 -0
  7. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidGeolocationErrors.kt +85 -0
  8. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidGeolocationOptions.kt +92 -0
  9. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidLocationSettings.kt +3 -0
  10. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidProviderRoute.kt +74 -0
  11. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/NitroBackgroundLocation.kt +132 -0
  12. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/NitroGeolocation.kt +219 -476
  13. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/AndroidBackgroundHttpSync.kt +134 -0
  14. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/AndroidBackgroundPermissions.kt +196 -0
  15. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/AndroidBackgroundSerialization.kt +266 -0
  16. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroActivityRecognitionReceiver.kt +13 -0
  17. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroBackgroundEventHub.kt +65 -0
  18. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroBackgroundHeadlessTaskService.kt +58 -0
  19. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroBackgroundLocationController.kt +710 -0
  20. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroBackgroundLocationService.kt +48 -0
  21. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroBackgroundNotificationFactory.kt +37 -0
  22. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroBackgroundStore.kt +655 -0
  23. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroBootReceiver.kt +26 -0
  24. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroGeofenceReceiver.kt +14 -0
  25. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroLocationUpdateReceiver.kt +37 -0
  26. package/android/src/test/java/com/margelo/nitro/nitrogeolocation/AndroidFusedLocationProviderTest.kt +64 -0
  27. package/android/src/test/java/com/margelo/nitro/nitrogeolocation/AndroidProviderRouteTest.kt +116 -0
  28. package/ios/IOSBackgroundHttpSync.swift +126 -0
  29. package/ios/IOSBackgroundLocationDelegate.swift +36 -0
  30. package/ios/IOSBackgroundMotion.swift +55 -0
  31. package/ios/IOSBackgroundSerialization.swift +539 -0
  32. package/ios/IOSGeolocationConversions.swift +131 -0
  33. package/ios/IOSGeolocationDelegate.swift +31 -0
  34. package/ios/IOSGeolocationErrors.swift +39 -0
  35. package/ios/IOSGeolocationOptions.swift +135 -0
  36. package/ios/NitroBackgroundLocation.swift +849 -0
  37. package/ios/NitroGeolocation.swift +14 -347
  38. package/nitrogen/generated/android/c++/JActivityRecognitionOptions.hpp +69 -0
  39. package/nitrogen/generated/android/c++/JAndroidBackgroundLocationOptions.hpp +74 -0
  40. package/nitrogen/generated/android/c++/JAndroidBackgroundLocationStatus.hpp +67 -0
  41. package/nitrogen/generated/android/c++/JAndroidBackgroundProvider.hpp +61 -0
  42. package/nitrogen/generated/android/c++/JAndroidForegroundServiceOptions.hpp +90 -0
  43. package/nitrogen/generated/android/c++/JBackgroundEventEnvelope.hpp +129 -0
  44. package/nitrogen/generated/android/c++/JBackgroundEventType.hpp +70 -0
  45. package/nitrogen/generated/android/c++/JBackgroundHttpMethod.hpp +61 -0
  46. package/nitrogen/generated/android/c++/JBackgroundHttpSyncOptions.hpp +131 -0
  47. package/nitrogen/generated/android/c++/JBackgroundHttpSyncResult.hpp +111 -0
  48. package/nitrogen/generated/android/c++/JBackgroundLocation.hpp +110 -0
  49. package/nitrogen/generated/android/c++/JBackgroundLocationOptions.hpp +162 -0
  50. package/nitrogen/generated/android/c++/JBackgroundLocationSource.hpp +73 -0
  51. package/nitrogen/generated/android/c++/JBackgroundLocationState.hpp +70 -0
  52. package/nitrogen/generated/android/c++/JBackgroundLocationStatus.hpp +126 -0
  53. package/nitrogen/generated/android/c++/JBackgroundPermissionResult.hpp +79 -0
  54. package/nitrogen/generated/android/c++/JBackgroundPermissionStatus.hpp +64 -0
  55. package/nitrogen/generated/android/c++/JBackgroundTrackingMode.hpp +61 -0
  56. package/nitrogen/generated/android/c++/JBatterySnapshot.hpp +61 -0
  57. package/nitrogen/generated/android/c++/JDetectedActivity.hpp +66 -0
  58. package/nitrogen/generated/android/c++/JDetectedActivityType.hpp +76 -0
  59. package/nitrogen/generated/android/c++/JFunc_void_BackgroundEventEnvelope.hpp +114 -0
  60. package/nitrogen/generated/android/c++/JFunc_void_BackgroundLocation.hpp +95 -0
  61. package/nitrogen/generated/android/c++/JGeofenceEvent.hpp +94 -0
  62. package/nitrogen/generated/android/c++/JGeofenceRegion.hpp +112 -0
  63. package/nitrogen/generated/android/c++/JGeofenceTransition.hpp +61 -0
  64. package/nitrogen/generated/android/c++/JGeofencingOptions.hpp +82 -0
  65. package/nitrogen/generated/android/c++/JGetStoredBackgroundEventsOptions.hpp +90 -0
  66. package/nitrogen/generated/android/c++/JGetStoredBackgroundLocationsOptions.hpp +69 -0
  67. package/nitrogen/generated/android/c++/JHybridNitroBackgroundLocationSpec.cpp +662 -0
  68. package/nitrogen/generated/android/c++/JHybridNitroBackgroundLocationSpec.hpp +89 -0
  69. package/nitrogen/generated/android/c++/JIOSBackgroundActivityType.hpp +67 -0
  70. package/nitrogen/generated/android/c++/JIOSBackgroundLocationOptions.hpp +79 -0
  71. package/nitrogen/generated/android/c++/JIOSBackgroundLocationStatus.hpp +61 -0
  72. package/nitrogen/generated/android/c++/JLocationProviderStatus.hpp +5 -1
  73. package/nitrogen/generated/android/c++/JStoredBackgroundEventEnvelope.hpp +115 -0
  74. package/nitrogen/generated/android/c++/JStoredBackgroundLocation.hpp +122 -0
  75. package/nitrogen/generated/android/c++/JVariant_NullType_Boolean_String_Double.cpp +34 -0
  76. package/nitrogen/generated/android/c++/JVariant_NullType_Boolean_String_Double.hpp +100 -0
  77. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/ActivityRecognitionOptions.kt +66 -0
  78. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/AndroidBackgroundLocationOptions.kt +66 -0
  79. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/AndroidBackgroundLocationStatus.kt +61 -0
  80. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/AndroidBackgroundProvider.kt +24 -0
  81. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/AndroidForegroundServiceOptions.kt +91 -0
  82. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundEventEnvelope.kt +96 -0
  83. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundEventType.kt +27 -0
  84. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundHttpMethod.kt +24 -0
  85. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundHttpSyncOptions.kt +101 -0
  86. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundHttpSyncResult.kt +71 -0
  87. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundLocation.kt +96 -0
  88. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundLocationOptions.kt +136 -0
  89. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundLocationSource.kt +28 -0
  90. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundLocationState.kt +27 -0
  91. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundLocationStatus.kt +116 -0
  92. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundPermissionResult.kt +71 -0
  93. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundPermissionStatus.kt +25 -0
  94. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundTrackingMode.kt +24 -0
  95. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BatterySnapshot.kt +56 -0
  96. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/DetectedActivity.kt +61 -0
  97. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/DetectedActivityType.kt +29 -0
  98. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void_BackgroundEventEnvelope.kt +80 -0
  99. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void_BackgroundLocation.kt +80 -0
  100. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeofenceEvent.kt +66 -0
  101. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeofenceRegion.kt +96 -0
  102. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeofenceTransition.kt +24 -0
  103. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeofencingOptions.kt +56 -0
  104. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GetStoredBackgroundEventsOptions.kt +66 -0
  105. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GetStoredBackgroundLocationsOptions.kt +66 -0
  106. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/HybridNitroBackgroundLocationSpec.kt +174 -0
  107. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/IOSBackgroundActivityType.kt +26 -0
  108. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/IOSBackgroundLocationOptions.kt +76 -0
  109. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/IOSBackgroundLocationStatus.kt +56 -0
  110. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/LocationProviderStatus.kt +7 -2
  111. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/StoredBackgroundEventEnvelope.kt +76 -0
  112. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/StoredBackgroundLocation.kt +111 -0
  113. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Variant_NullType_Boolean_String_Double.kt +88 -0
  114. package/nitrogen/generated/android/nitrogeolocation+autolinking.cmake +3 -0
  115. package/nitrogen/generated/android/nitrogeolocationOnLoad.cpp +20 -0
  116. package/nitrogen/generated/ios/NitroGeolocation-Swift-Cxx-Bridge.cpp +104 -15
  117. package/nitrogen/generated/ios/NitroGeolocation-Swift-Cxx-Bridge.hpp +1107 -50
  118. package/nitrogen/generated/ios/NitroGeolocation-Swift-Cxx-Umbrella.hpp +102 -0
  119. package/nitrogen/generated/ios/NitroGeolocationAutolinking.mm +8 -0
  120. package/nitrogen/generated/ios/NitroGeolocationAutolinking.swift +15 -3
  121. package/nitrogen/generated/ios/c++/HybridNitroBackgroundLocationSpecSwift.cpp +11 -0
  122. package/nitrogen/generated/ios/c++/HybridNitroBackgroundLocationSpecSwift.hpp +416 -0
  123. package/nitrogen/generated/ios/swift/ActivityRecognitionOptions.swift +96 -0
  124. package/nitrogen/generated/ios/swift/AndroidBackgroundLocationOptions.swift +76 -0
  125. package/nitrogen/generated/ios/swift/AndroidBackgroundLocationStatus.swift +58 -0
  126. package/nitrogen/generated/ios/swift/AndroidBackgroundProvider.swift +44 -0
  127. package/nitrogen/generated/ios/swift/AndroidForegroundServiceOptions.swift +160 -0
  128. package/nitrogen/generated/ios/swift/BackgroundEventEnvelope.swift +110 -0
  129. package/nitrogen/generated/ios/swift/BackgroundEventType.swift +56 -0
  130. package/nitrogen/generated/ios/swift/BackgroundHttpMethod.swift +44 -0
  131. package/nitrogen/generated/ios/swift/BackgroundHttpSyncOptions.swift +259 -0
  132. package/nitrogen/generated/ios/swift/BackgroundHttpSyncResult.swift +87 -0
  133. package/nitrogen/generated/ios/swift/BackgroundLocation.swift +118 -0
  134. package/nitrogen/generated/ios/swift/BackgroundLocationOptions.swift +292 -0
  135. package/nitrogen/generated/ios/swift/BackgroundLocationSource.swift +60 -0
  136. package/nitrogen/generated/ios/swift/BackgroundLocationState.swift +56 -0
  137. package/nitrogen/generated/ios/swift/BackgroundLocationStatus.swift +124 -0
  138. package/nitrogen/generated/ios/swift/BackgroundPermissionResult.swift +81 -0
  139. package/nitrogen/generated/ios/swift/BackgroundPermissionStatus.swift +48 -0
  140. package/nitrogen/generated/ios/swift/BackgroundTrackingMode.swift +44 -0
  141. package/nitrogen/generated/ios/swift/BatterySnapshot.swift +60 -0
  142. package/nitrogen/generated/ios/swift/DetectedActivity.swift +39 -0
  143. package/nitrogen/generated/ios/swift/DetectedActivityType.swift +64 -0
  144. package/nitrogen/generated/ios/swift/Func_void_BackgroundEventEnvelope.swift +46 -0
  145. package/nitrogen/generated/ios/swift/Func_void_BackgroundHttpSyncResult.swift +46 -0
  146. package/nitrogen/generated/ios/swift/Func_void_BackgroundLocation.swift +46 -0
  147. package/nitrogen/generated/ios/swift/Func_void_BackgroundLocationStatus.swift +46 -0
  148. package/nitrogen/generated/ios/swift/Func_void_BackgroundPermissionResult.swift +46 -0
  149. package/nitrogen/generated/ios/swift/Func_void_std__optional_BackgroundLocationOptions_.swift +46 -0
  150. package/nitrogen/generated/ios/swift/Func_void_std__vector_GeofenceRegion_.swift +46 -0
  151. package/nitrogen/generated/ios/swift/Func_void_std__vector_StoredBackgroundEventEnvelope_.swift +46 -0
  152. package/nitrogen/generated/ios/swift/Func_void_std__vector_StoredBackgroundLocation_.swift +46 -0
  153. package/nitrogen/generated/ios/swift/GeofenceEvent.swift +50 -0
  154. package/nitrogen/generated/ios/swift/GeofenceRegion.swift +195 -0
  155. package/nitrogen/generated/ios/swift/GeofenceTransition.swift +44 -0
  156. package/nitrogen/generated/ios/swift/GeofencingOptions.swift +66 -0
  157. package/nitrogen/generated/ios/swift/GetStoredBackgroundEventsOptions.swift +102 -0
  158. package/nitrogen/generated/ios/swift/GetStoredBackgroundLocationsOptions.swift +96 -0
  159. package/nitrogen/generated/ios/swift/HybridNitroBackgroundLocationSpec.swift +81 -0
  160. package/nitrogen/generated/ios/swift/HybridNitroBackgroundLocationSpec_cxx.swift +654 -0
  161. package/nitrogen/generated/ios/swift/IOSBackgroundActivityType.swift +52 -0
  162. package/nitrogen/generated/ios/swift/IOSBackgroundLocationOptions.swift +125 -0
  163. package/nitrogen/generated/ios/swift/IOSBackgroundLocationStatus.swift +34 -0
  164. package/nitrogen/generated/ios/swift/LocationProviderStatus.swift +19 -1
  165. package/nitrogen/generated/ios/swift/StoredBackgroundEventEnvelope.swift +54 -0
  166. package/nitrogen/generated/ios/swift/StoredBackgroundLocation.swift +120 -0
  167. package/nitrogen/generated/ios/swift/Variant_NullType_Bool_String_Double.swift +34 -0
  168. package/nitrogen/generated/shared/c++/ActivityRecognitionOptions.hpp +95 -0
  169. package/nitrogen/generated/shared/c++/AndroidBackgroundLocationOptions.hpp +100 -0
  170. package/nitrogen/generated/shared/c++/AndroidBackgroundLocationStatus.hpp +93 -0
  171. package/nitrogen/generated/shared/c++/AndroidBackgroundProvider.hpp +80 -0
  172. package/nitrogen/generated/shared/c++/AndroidForegroundServiceOptions.hpp +116 -0
  173. package/nitrogen/generated/shared/c++/BackgroundEventEnvelope.hpp +140 -0
  174. package/nitrogen/generated/shared/c++/BackgroundEventType.hpp +92 -0
  175. package/nitrogen/generated/shared/c++/BackgroundHttpMethod.hpp +80 -0
  176. package/nitrogen/generated/shared/c++/BackgroundHttpSyncOptions.hpp +129 -0
  177. package/nitrogen/generated/shared/c++/BackgroundHttpSyncResult.hpp +101 -0
  178. package/nitrogen/generated/shared/c++/BackgroundLocation.hpp +134 -0
  179. package/nitrogen/generated/shared/c++/BackgroundLocationOptions.hpp +174 -0
  180. package/nitrogen/generated/shared/c++/BackgroundLocationSource.hpp +96 -0
  181. package/nitrogen/generated/shared/c++/BackgroundLocationState.hpp +92 -0
  182. package/nitrogen/generated/shared/c++/BackgroundLocationStatus.hpp +158 -0
  183. package/nitrogen/generated/shared/c++/BackgroundPermissionResult.hpp +107 -0
  184. package/nitrogen/generated/shared/c++/BackgroundPermissionStatus.hpp +84 -0
  185. package/nitrogen/generated/shared/c++/BackgroundTrackingMode.hpp +80 -0
  186. package/nitrogen/generated/shared/c++/BatterySnapshot.hpp +87 -0
  187. package/nitrogen/generated/shared/c++/DetectedActivity.hpp +92 -0
  188. package/nitrogen/generated/shared/c++/DetectedActivityType.hpp +100 -0
  189. package/nitrogen/generated/shared/c++/GeofenceEvent.hpp +103 -0
  190. package/nitrogen/generated/shared/c++/GeofenceRegion.hpp +123 -0
  191. package/nitrogen/generated/shared/c++/GeofenceTransition.hpp +80 -0
  192. package/nitrogen/generated/shared/c++/GeofencingOptions.hpp +90 -0
  193. package/nitrogen/generated/shared/c++/GetStoredBackgroundEventsOptions.hpp +98 -0
  194. package/nitrogen/generated/shared/c++/GetStoredBackgroundLocationsOptions.hpp +95 -0
  195. package/nitrogen/generated/shared/c++/HybridNitroBackgroundLocationSpec.cpp +47 -0
  196. package/nitrogen/generated/shared/c++/HybridNitroBackgroundLocationSpec.hpp +133 -0
  197. package/nitrogen/generated/shared/c++/IOSBackgroundActivityType.hpp +88 -0
  198. package/nitrogen/generated/shared/c++/IOSBackgroundLocationOptions.hpp +105 -0
  199. package/nitrogen/generated/shared/c++/IOSBackgroundLocationStatus.hpp +87 -0
  200. package/nitrogen/generated/shared/c++/LocationProviderStatus.hpp +5 -1
  201. package/nitrogen/generated/shared/c++/StoredBackgroundEventEnvelope.hpp +108 -0
  202. package/nitrogen/generated/shared/c++/StoredBackgroundLocation.hpp +146 -0
  203. package/package.json +17 -6
  204. package/src/NitroGeolocation.nitro.ts +4 -4
  205. package/src/api/getCurrentPosition.ts +1 -1
  206. package/src/api/requestLocationSettings.ts +3 -2
  207. package/src/background/NitroBackgroundLocation.nitro.ts +83 -0
  208. package/src/background/index.ts +200 -0
  209. package/src/background/index.web.ts +120 -0
  210. package/src/background/task.ts +13 -0
  211. package/src/background/types.ts +328 -0
  212. package/src/compat/index.web.ts +141 -0
  213. package/src/index.tsx +3 -0
  214. package/src/index.web.tsx +41 -0
  215. package/src/publicTypes.ts +6 -5
  216. package/src/types.ts +3 -0
  217. package/src/web/browser.ts +171 -0
  218. package/src/web/index.ts +167 -0
  219. package/src/web/useWatchPosition.ts +76 -0
  220. package/src/web/watch.ts +81 -0
  221. package/src/devtools/index.test.ts +0 -54
  222. package/src/utils/errors.test.ts +0 -65
  223. package/src/utils/provider.test.ts +0 -303
@@ -0,0 +1,310 @@
1
+ package com.margelo.nitro.nitrogeolocation
2
+
3
+ import android.location.Location
4
+ import android.os.Handler
5
+ import android.os.Looper
6
+ import com.google.android.gms.location.CurrentLocationRequest
7
+ import com.google.android.gms.location.FusedLocationProviderClient
8
+ import com.google.android.gms.location.LocationCallback
9
+ import com.google.android.gms.location.LocationResult
10
+ import com.google.android.gms.tasks.CancellationTokenSource
11
+ import java.util.concurrent.atomic.AtomicBoolean
12
+
13
+ private const val FUSED_ATTEMPT_TIMEOUT_MS = 15_000L
14
+ private const val FUSED_FALLBACK_RESERVED_TIMEOUT_MS = 10_000L
15
+
16
+ internal class AndroidFusedLocationProvider(
17
+ private val fusedLocationClient: FusedLocationProviderClient,
18
+ private val isCachedLocationValid: (Location, ParsedOptions) -> Boolean,
19
+ private val effectiveMaximumAge: (ParsedOptions) -> Double,
20
+ private val locationToPosition: (Location, LocationProviderUsed?) -> GeolocationResponse
21
+ ) {
22
+ fun getCurrentPosition(
23
+ success: (GeolocationResponse) -> Unit,
24
+ error: ((LocationError) -> Unit)?,
25
+ options: ParsedOptions,
26
+ deadlineElapsedRealtime: Long
27
+ ) {
28
+ if (effectiveMaximumAge(options) > 0.0) {
29
+ getCachedLocation(options) { cachedLocation, fusedError ->
30
+ if (cachedLocation != null) {
31
+ success(locationToPosition(cachedLocation, LocationProviderUsed.FUSED))
32
+ return@getCachedLocation
33
+ }
34
+ if (fusedError != null) {
35
+ error?.invoke(fusedError)
36
+ return@getCachedLocation
37
+ }
38
+
39
+ requestFreshLocation(success, error, options, deadlineElapsedRealtime)
40
+ }
41
+ return
42
+ }
43
+
44
+ requestFreshLocation(success, error, options, deadlineElapsedRealtime)
45
+ }
46
+
47
+ fun getLastKnownPosition(
48
+ success: (GeolocationResponse) -> Unit,
49
+ error: ((LocationError) -> Unit)?,
50
+ options: ParsedOptions
51
+ ) {
52
+ getCachedLocation(options) { cachedLocation, fusedError ->
53
+ if (cachedLocation != null) {
54
+ success(locationToPosition(cachedLocation, LocationProviderUsed.FUSED))
55
+ return@getCachedLocation
56
+ }
57
+ if (fusedError != null) {
58
+ error?.invoke(fusedError)
59
+ return@getCachedLocation
60
+ }
61
+
62
+ error?.invoke(createLocationError(
63
+ POSITION_UNAVAILABLE,
64
+ "No cached location available"
65
+ ))
66
+ }
67
+ }
68
+
69
+ fun requestWatchUpdates(
70
+ options: ParsedOptions,
71
+ callback: LocationCallback,
72
+ onInactiveStart: () -> Unit,
73
+ onFailure: (LocationError?) -> Unit
74
+ ) {
75
+ try {
76
+ fusedLocationClient.requestLocationUpdates(
77
+ buildFusedLocationRequest(options),
78
+ callback,
79
+ Looper.getMainLooper()
80
+ )
81
+ .addOnSuccessListener {
82
+ onInactiveStart()
83
+ }
84
+ .addOnFailureListener { exception ->
85
+ onFailure(createFusedRequestFailureError(exception))
86
+ }
87
+ .addOnCanceledListener {
88
+ onFailure(null)
89
+ }
90
+ } catch (e: SecurityException) {
91
+ onFailure(createFusedSecurityError(e.message))
92
+ } catch (_: Exception) {
93
+ onFailure(null)
94
+ }
95
+ }
96
+
97
+ private fun getCachedLocation(
98
+ options: ParsedOptions,
99
+ completion: (Location?, LocationError?) -> Unit
100
+ ) {
101
+ // Fused lastLocation is not requested with LocationRequest granularity,
102
+ // so it cannot prove that a cached fix satisfies coarse-only callers.
103
+ if (options.granularity == AndroidGranularity.COARSE) {
104
+ completion(null, null)
105
+ return
106
+ }
107
+
108
+ try {
109
+ fusedLocationClient.lastLocation
110
+ .addOnSuccessListener { location ->
111
+ completion(location?.takeIf { isCachedLocationValid(it, options) }, null)
112
+ }
113
+ .addOnFailureListener { exception ->
114
+ completion(null, createPermissionErrorOrNull(exception))
115
+ }
116
+ .addOnCanceledListener {
117
+ completion(null, null)
118
+ }
119
+ } catch (e: SecurityException) {
120
+ completion(null, createFusedSecurityError(e.message))
121
+ }
122
+ }
123
+
124
+ private fun requestFreshLocation(
125
+ success: (GeolocationResponse) -> Unit,
126
+ error: ((LocationError) -> Unit)?,
127
+ options: ParsedOptions,
128
+ deadlineElapsedRealtime: Long
129
+ ) {
130
+ val handler = Handler(Looper.getMainLooper())
131
+ val didComplete = AtomicBoolean(false)
132
+ val remainingTimeoutMillis = remainingTimeoutMillis(deadlineElapsedRealtime)
133
+
134
+ if (remainingTimeoutMillis <= 0L) {
135
+ error?.invoke(createPositionTimeoutError(options))
136
+ return
137
+ }
138
+ val fusedAttemptTimeoutMillis = fusedAttemptTimeoutMillis(remainingTimeoutMillis)
139
+ val cancellationTokenSource = CancellationTokenSource()
140
+ var locationUpdateCallback: LocationCallback? = null
141
+
142
+ fun complete(result: PositionResult) {
143
+ if (!didComplete.compareAndSet(false, true)) return
144
+
145
+ handler.removeCallbacksAndMessages(null)
146
+ locationUpdateCallback?.let { callback ->
147
+ try {
148
+ fusedLocationClient.removeLocationUpdates(callback)
149
+ } catch (_: Exception) {
150
+ // Ignore cleanup races.
151
+ }
152
+ }
153
+ locationUpdateCallback = null
154
+ try {
155
+ cancellationTokenSource.cancel()
156
+ } catch (_: Exception) {
157
+ // Ignore cleanup races.
158
+ }
159
+
160
+ when (result) {
161
+ is PositionResult.Success -> success(result.position)
162
+ is PositionResult.Failure -> error?.invoke(result.error)
163
+ }
164
+ }
165
+
166
+ val timeoutRunnable = Runnable {
167
+ complete(PositionResult.Failure(createPositionTimeoutError(options)))
168
+ }
169
+
170
+ try {
171
+ if (options.waitForAccurateLocation) {
172
+ val initialUpdateMaxAge = fusedInitialUpdateMaxAge(
173
+ options,
174
+ effectiveMaximumAge(options)
175
+ )
176
+ val request = buildFusedLocationRequest(
177
+ options.copy(maxUpdateAge = initialUpdateMaxAge),
178
+ maxUpdatesOverride = 1,
179
+ includeDistanceFilter = false
180
+ )
181
+ val callback = object : LocationCallback() {
182
+ override fun onLocationResult(result: LocationResult) {
183
+ val location = result.lastLocation
184
+ if (location != null) {
185
+ complete(PositionResult.Success(
186
+ locationToPosition(location, LocationProviderUsed.FUSED)
187
+ ))
188
+ } else {
189
+ complete(PositionResult.Failure(createLocationError(
190
+ POSITION_UNAVAILABLE,
191
+ "Unable to get fused location"
192
+ )))
193
+ }
194
+ }
195
+ }
196
+ locationUpdateCallback = callback
197
+
198
+ fusedLocationClient.requestLocationUpdates(
199
+ request,
200
+ callback,
201
+ Looper.getMainLooper()
202
+ )
203
+ .addOnFailureListener { exception ->
204
+ complete(PositionResult.Failure(
205
+ createFusedRequestFailureError(exception)
206
+ ))
207
+ }
208
+ .addOnCanceledListener {
209
+ complete(PositionResult.Failure(createPositionTimeoutError(options)))
210
+ }
211
+
212
+ handler.postDelayed(timeoutRunnable, fusedAttemptTimeoutMillis)
213
+ return
214
+ }
215
+
216
+ val request = CurrentLocationRequest.Builder()
217
+ .setPriority(options.androidAccuracy.gmsPriority())
218
+ .setGranularity(options.granularity.gmsGranularity())
219
+ .setMaxUpdateAgeMillis(
220
+ coerceNonNegativeMillis(
221
+ fusedInitialUpdateMaxAge(options, effectiveMaximumAge(options))
222
+ )
223
+ )
224
+ .setDurationMillis(fusedAttemptTimeoutMillis)
225
+ .build()
226
+
227
+ fusedLocationClient.getCurrentLocation(
228
+ request,
229
+ cancellationTokenSource.token
230
+ )
231
+ .addOnSuccessListener { location ->
232
+ if (location != null) {
233
+ complete(PositionResult.Success(
234
+ locationToPosition(location, LocationProviderUsed.FUSED)
235
+ ))
236
+ } else {
237
+ complete(PositionResult.Failure(createLocationError(
238
+ POSITION_UNAVAILABLE,
239
+ "Unable to get fused location"
240
+ )))
241
+ }
242
+ }
243
+ .addOnFailureListener { exception ->
244
+ complete(PositionResult.Failure(
245
+ createFusedRequestFailureError(exception)
246
+ ))
247
+ }
248
+ .addOnCanceledListener {
249
+ complete(PositionResult.Failure(createPositionTimeoutError(options)))
250
+ }
251
+
252
+ handler.postDelayed(timeoutRunnable, fusedAttemptTimeoutMillis)
253
+ } catch (e: SecurityException) {
254
+ complete(PositionResult.Failure(createFusedSecurityError(e.message)))
255
+ } catch (e: Exception) {
256
+ complete(PositionResult.Failure(createLocationError(
257
+ POSITION_UNAVAILABLE,
258
+ "Unable to request fused location: ${e.message}"
259
+ )))
260
+ }
261
+ }
262
+
263
+ private fun createPermissionErrorOrNull(exception: Exception): LocationError? {
264
+ return if (exception is SecurityException) {
265
+ createFusedSecurityError(exception.message)
266
+ } else {
267
+ null
268
+ }
269
+ }
270
+ }
271
+
272
+ internal fun createFusedRequestFailureError(exception: Exception): LocationError {
273
+ return if (exception is SecurityException) {
274
+ createFusedSecurityError(exception.message)
275
+ } else {
276
+ createLocationError(
277
+ POSITION_UNAVAILABLE,
278
+ "Unable to request fused location: ${exception.message}"
279
+ )
280
+ }
281
+ }
282
+
283
+ internal fun createFusedSecurityError(message: String?): LocationError {
284
+ return createLocationError(
285
+ PERMISSION_DENIED,
286
+ "Security exception: ${message ?: "unknown error"}"
287
+ )
288
+ }
289
+
290
+ internal fun fusedInitialUpdateMaxAge(
291
+ options: ParsedOptions,
292
+ effectiveMaximumAge: Double
293
+ ): Double {
294
+ return options.maxUpdateAge ?: effectiveMaximumAge
295
+ }
296
+
297
+ private fun fusedAttemptTimeoutMillis(remainingTimeoutMillis: Long): Long {
298
+ if (remainingTimeoutMillis == Long.MAX_VALUE) {
299
+ return FUSED_ATTEMPT_TIMEOUT_MS
300
+ }
301
+
302
+ if (remainingTimeoutMillis <= FUSED_FALLBACK_RESERVED_TIMEOUT_MS) {
303
+ return (remainingTimeoutMillis / 2L).coerceAtLeast(1L)
304
+ }
305
+
306
+ return minOf(
307
+ FUSED_ATTEMPT_TIMEOUT_MS,
308
+ (remainingTimeoutMillis - FUSED_FALLBACK_RESERVED_TIMEOUT_MS).coerceAtLeast(1L)
309
+ )
310
+ }
@@ -0,0 +1,31 @@
1
+ package com.margelo.nitro.nitrogeolocation
2
+
3
+ import com.google.android.gms.location.LocationRequest as GmsLocationRequest
4
+
5
+ internal fun buildFusedLocationRequest(
6
+ options: ParsedOptions,
7
+ maxUpdatesOverride: Int? = null,
8
+ includeDistanceFilter: Boolean = true
9
+ ): GmsLocationRequest {
10
+ val builder = GmsLocationRequest
11
+ .Builder(options.androidAccuracy.gmsPriority(), coercePositiveMillis(options.interval))
12
+ .setMinUpdateIntervalMillis(coercePositiveMillis(options.fastestInterval))
13
+ .setGranularity(options.granularity.gmsGranularity())
14
+ .setWaitForAccurateLocation(options.waitForAccurateLocation)
15
+ .setMaxUpdateDelayMillis(coerceNonNegativeMillis(options.maxUpdateDelay))
16
+
17
+ if (includeDistanceFilter) {
18
+ builder.setMinUpdateDistanceMeters(options.distanceFilter.toFloat())
19
+ }
20
+
21
+ options.maxUpdateAge?.let { value ->
22
+ builder.setMaxUpdateAgeMillis(coerceNonNegativeMillis(value))
23
+ }
24
+
25
+ val maxUpdates = maxUpdatesOverride ?: options.maxUpdates
26
+ if (maxUpdates != null) {
27
+ builder.setMaxUpdates(maxUpdates)
28
+ }
29
+
30
+ return builder.build()
31
+ }
@@ -0,0 +1,71 @@
1
+ package com.margelo.nitro.nitrogeolocation
2
+
3
+ import android.location.Address
4
+ import android.location.Location
5
+
6
+ internal fun Location.toGeolocationResponse(
7
+ providerOverride: LocationProviderUsed? = null
8
+ ): GeolocationResponse {
9
+ val coords = GeolocationCoordinates(
10
+ latitude = latitude,
11
+ longitude = longitude,
12
+ altitude = altitudeValue(),
13
+ accuracy = accuracy.toDouble(),
14
+ altitudeAccuracy = altitudeAccuracyValue(),
15
+ heading = headingValue(),
16
+ speed = speedValue()
17
+ )
18
+
19
+ return GeolocationResponse(
20
+ coords = coords,
21
+ timestamp = time.toDouble(),
22
+ mocked = isMocked(),
23
+ provider = providerOverride ?: providerUsed()
24
+ )
25
+ }
26
+
27
+ internal fun Address.toGeocodedLocation(): GeocodedLocation? {
28
+ if (!hasLatitude() || !hasLongitude()) {
29
+ return null
30
+ }
31
+
32
+ return GeocodedLocation(
33
+ latitude = latitude,
34
+ longitude = longitude,
35
+ accuracy = null
36
+ )
37
+ }
38
+
39
+ internal fun Address.toReverseGeocodedAddress(): ReverseGeocodedAddress {
40
+ return ReverseGeocodedAddress(
41
+ country = countryName.nonBlankOrNull(),
42
+ region = adminArea.nonBlankOrNull(),
43
+ city = (locality ?: subAdminArea).nonBlankOrNull(),
44
+ district = subLocality.nonBlankOrNull(),
45
+ street = formatStreet(),
46
+ postalCode = postalCode.nonBlankOrNull(),
47
+ formattedAddress = formatAddressLines()
48
+ )
49
+ }
50
+
51
+ internal fun Address.formatStreet(): String? {
52
+ return listOf(subThoroughfare, thoroughfare)
53
+ .mapNotNull { it.nonBlankOrNull() }
54
+ .joinToString(" ")
55
+ .nonBlankOrNull()
56
+ }
57
+
58
+ internal fun Address.formatAddressLines(): String? {
59
+ if (maxAddressLineIndex < 0) {
60
+ return null
61
+ }
62
+
63
+ return (0..maxAddressLineIndex)
64
+ .mapNotNull { index -> getAddressLine(index).nonBlankOrNull() }
65
+ .joinToString(", ")
66
+ .nonBlankOrNull()
67
+ }
68
+
69
+ internal fun String?.nonBlankOrNull(): String? {
70
+ return this?.trim()?.takeIf { it.isNotEmpty() }
71
+ }
@@ -0,0 +1,85 @@
1
+ package com.margelo.nitro.nitrogeolocation
2
+
3
+ import android.os.SystemClock
4
+
5
+ internal const val NO_LOCATION_PROVIDER_AVAILABLE_MESSAGE = "No location provider available"
6
+ internal const val NO_APPROXIMATE_LOCATION_PROVIDER_AVAILABLE_MESSAGE =
7
+ "No location provider is available for approximate location. " +
8
+ "ACCESS_COARSE_LOCATION is granted, but no enabled coarse-compatible provider is available."
9
+
10
+ internal const val INTERNAL_ERROR = -1.0
11
+ internal const val PERMISSION_DENIED = 1.0
12
+ internal const val POSITION_UNAVAILABLE = 2.0
13
+ internal const val TIMEOUT = 3.0
14
+ internal const val PLAY_SERVICE_NOT_AVAILABLE = 4.0
15
+ internal const val SETTINGS_NOT_SATISFIED = 5.0
16
+
17
+ internal fun createLocationAvailability(
18
+ available: Boolean,
19
+ reason: String?
20
+ ): LocationAvailability {
21
+ return LocationAvailability(
22
+ available = available,
23
+ reason = reason
24
+ )
25
+ }
26
+
27
+ internal fun createLocationError(code: Double, message: String): LocationError {
28
+ return LocationError(
29
+ code = code,
30
+ message = message
31
+ )
32
+ }
33
+
34
+ internal fun createPlayServicesUnavailableError(): LocationError {
35
+ return createLocationError(
36
+ PLAY_SERVICE_NOT_AVAILABLE,
37
+ "Google Play Services location provider is not available."
38
+ )
39
+ }
40
+
41
+ internal fun createPositionTimeoutError(options: ParsedOptions): LocationError {
42
+ val timeoutSeconds = options.timeout / 1000.0
43
+ val message = String.format("Unable to fetch location within %.1fs.", timeoutSeconds)
44
+ return createLocationError(TIMEOUT, message)
45
+ }
46
+
47
+ internal fun createRequestDeadlineElapsedRealtime(timeout: Double): Long {
48
+ val now = SystemClock.elapsedRealtime()
49
+ val timeoutMillis = coerceTimeoutMillis(timeout)
50
+ val maxTimeoutMillis = Long.MAX_VALUE - now
51
+
52
+ return if (timeoutMillis >= maxTimeoutMillis) {
53
+ Long.MAX_VALUE
54
+ } else {
55
+ now + timeoutMillis
56
+ }
57
+ }
58
+
59
+ internal fun remainingTimeoutMillis(deadlineElapsedRealtime: Long): Long {
60
+ return (deadlineElapsedRealtime - SystemClock.elapsedRealtime()).coerceAtLeast(0L)
61
+ }
62
+
63
+ internal fun coerceTimeoutMillis(timeout: Double): Long {
64
+ return when {
65
+ timeout.isNaN() || timeout <= 0.0 -> 0L
66
+ timeout.isInfinite() || timeout >= Long.MAX_VALUE.toDouble() -> Long.MAX_VALUE
67
+ else -> timeout.toLong()
68
+ }
69
+ }
70
+
71
+ internal fun coercePositiveMillis(value: Double): Long {
72
+ return when {
73
+ value.isNaN() || value <= 0.0 -> 1L
74
+ value.isInfinite() || value >= Long.MAX_VALUE.toDouble() -> Long.MAX_VALUE
75
+ else -> value.toLong()
76
+ }
77
+ }
78
+
79
+ internal fun coerceNonNegativeMillis(value: Double): Long {
80
+ return when {
81
+ value.isNaN() || value <= 0.0 -> 0L
82
+ value.isInfinite() || value >= Long.MAX_VALUE.toDouble() -> Long.MAX_VALUE
83
+ else -> value.toLong()
84
+ }
85
+ }
@@ -0,0 +1,92 @@
1
+ package com.margelo.nitro.nitrogeolocation
2
+
3
+ import android.os.CancellationSignal
4
+ import android.os.Handler
5
+ import android.os.SystemClock
6
+ import java.util.UUID
7
+
8
+ internal data class ParsedOptions(
9
+ val timeout: Double,
10
+ val maximumAge: Double,
11
+ val androidAccuracy: AndroidAccuracyResolution,
12
+ val interval: Double,
13
+ val fastestInterval: Double,
14
+ val distanceFilter: Double,
15
+ val granularity: AndroidGranularity,
16
+ val waitForAccurateLocation: Boolean,
17
+ val maxUpdateAge: Double?,
18
+ val maxUpdateDelay: Double,
19
+ val maxUpdates: Int?
20
+ ) {
21
+ companion object {
22
+ private const val DEFAULT_TIMEOUT = 10.0 * 60 * 1000 // 10 minutes in ms
23
+ private const val DEFAULT_MAXIMUM_AGE = 0.0
24
+ private const val DEFAULT_INTERVAL = 1000.0
25
+ private const val DEFAULT_FASTEST_INTERVAL = 100.0
26
+ private const val DEFAULT_DISTANCE_FILTER = 0.0
27
+ private const val DEFAULT_MAX_UPDATE_DELAY = 0.0
28
+
29
+ fun parse(
30
+ options: LocationRequestOptions?,
31
+ defaultMaximumAge: Double = DEFAULT_MAXIMUM_AGE
32
+ ): ParsedOptions {
33
+ val enableHighAccuracy = options?.enableHighAccuracy ?: false
34
+ val maxUpdates = options?.maxUpdates?.let { value ->
35
+ if (!value.isFinite()) {
36
+ 0
37
+ } else {
38
+ value.toInt()
39
+ }
40
+ }
41
+
42
+ return ParsedOptions(
43
+ timeout = options?.timeout ?: DEFAULT_TIMEOUT,
44
+ maximumAge = options?.maximumAge ?: defaultMaximumAge,
45
+ androidAccuracy = resolveAndroidAccuracy(
46
+ options?.accuracy,
47
+ enableHighAccuracy
48
+ ),
49
+ interval = options?.interval ?: DEFAULT_INTERVAL,
50
+ fastestInterval = options?.fastestInterval ?: DEFAULT_FASTEST_INTERVAL,
51
+ distanceFilter = options?.distanceFilter ?: DEFAULT_DISTANCE_FILTER,
52
+ granularity = options?.granularity ?: AndroidGranularity.PERMISSION,
53
+ waitForAccurateLocation = options?.waitForAccurateLocation ?: false,
54
+ maxUpdateAge = options?.maxUpdateAge,
55
+ maxUpdateDelay = options?.maxUpdateDelay ?: DEFAULT_MAX_UPDATE_DELAY,
56
+ maxUpdates = maxUpdates
57
+ )
58
+ }
59
+
60
+ fun parseLastKnown(options: LocationRequestOptions?): ParsedOptions {
61
+ return parse(options, defaultMaximumAge = Double.POSITIVE_INFINITY)
62
+ }
63
+ }
64
+ }
65
+
66
+ internal data class WatchSubscription(
67
+ val token: String,
68
+ val success: (GeolocationResponse) -> Unit,
69
+ val error: ((LocationError) -> Unit)?,
70
+ val options: ParsedOptions,
71
+ var deliveredUpdates: Int = 0
72
+ )
73
+
74
+ internal sealed interface PositionResult {
75
+ data class Success(val position: GeolocationResponse) : PositionResult
76
+ data class Failure(val error: LocationError) : PositionResult
77
+ }
78
+
79
+ internal data class PositionRequest(
80
+ val id: UUID,
81
+ val resolver: (PositionResult) -> Unit,
82
+ val options: ParsedOptions,
83
+ val handler: Handler,
84
+ val providers: List<String>,
85
+ val deadlineElapsedRealtime: Long,
86
+ var providerIndex: Int = 0,
87
+ var cancellationSignal: CancellationSignal? = null
88
+ ) {
89
+ fun remainingTimeoutMillis(): Long {
90
+ return (deadlineElapsedRealtime - SystemClock.elapsedRealtime()).coerceAtLeast(0L)
91
+ }
92
+ }
@@ -134,12 +134,15 @@ internal class AndroidLocationSettings(
134
134
  private fun createProviderStatus(
135
135
  googleLocationAccuracyEnabled: Boolean?
136
136
  ): LocationProviderStatus {
137
+ val googlePlayServicesAvailable = isGooglePlayServicesAvailable()
138
+
137
139
  return LocationProviderStatus(
138
140
  locationServicesEnabled = hasServicesEnabled(),
139
141
  backgroundModeEnabled = hasBackgroundLocationPermission(),
140
142
  gpsAvailable = isProviderEnabled(AndroidLocationManager.GPS_PROVIDER),
141
143
  networkAvailable = isProviderEnabled(AndroidLocationManager.NETWORK_PROVIDER),
142
144
  passiveAvailable = isProviderEnabled(AndroidLocationManager.PASSIVE_PROVIDER),
145
+ googlePlayServicesAvailable = googlePlayServicesAvailable,
143
146
  googleLocationAccuracyEnabled = googleLocationAccuracyEnabled
144
147
  )
145
148
  }
@@ -0,0 +1,74 @@
1
+ package com.margelo.nitro.nitrogeolocation
2
+
3
+ internal enum class AndroidProviderRoute {
4
+ FUSED,
5
+ PLATFORM
6
+ }
7
+
8
+ internal fun selectAndroidProviderRoute(
9
+ locationProvider: LocationProvider?,
10
+ googlePlayServicesAvailable: Boolean
11
+ ): AndroidProviderRoute {
12
+ if (locationProvider == LocationProvider.ANDROID_PLATFORM) {
13
+ return AndroidProviderRoute.PLATFORM
14
+ }
15
+
16
+ return if (googlePlayServicesAvailable) {
17
+ AndroidProviderRoute.FUSED
18
+ } else {
19
+ AndroidProviderRoute.PLATFORM
20
+ }
21
+ }
22
+
23
+ internal fun selectAndroidFallbackRouteAfterFusedFailure(
24
+ @Suppress("UNUSED_PARAMETER") locationProvider: LocationProvider?
25
+ ): AndroidProviderRoute {
26
+ return AndroidProviderRoute.PLATFORM
27
+ }
28
+
29
+ private fun runAndroidProviderFallbackAfterFusedFailure(
30
+ locationProvider: LocationProvider?,
31
+ runPlatformFallback: () -> Unit,
32
+ failWithoutFallback: () -> Unit
33
+ ) {
34
+ when (selectAndroidFallbackRouteAfterFusedFailure(locationProvider)) {
35
+ AndroidProviderRoute.PLATFORM -> runPlatformFallback()
36
+ AndroidProviderRoute.FUSED -> failWithoutFallback()
37
+ }
38
+ }
39
+
40
+ internal fun runAndroidCurrentPositionFallbackAfterFusedFailure(
41
+ locationProvider: LocationProvider?,
42
+ runPlatformFallback: () -> Unit,
43
+ failWithoutFallback: () -> Unit
44
+ ) {
45
+ runAndroidProviderFallbackAfterFusedFailure(
46
+ locationProvider = locationProvider,
47
+ runPlatformFallback = runPlatformFallback,
48
+ failWithoutFallback = failWithoutFallback
49
+ )
50
+ }
51
+
52
+ internal fun runAndroidLastKnownPositionFallbackAfterFusedFailure(
53
+ locationProvider: LocationProvider?,
54
+ runPlatformFallback: () -> Unit,
55
+ failWithoutFallback: () -> Unit
56
+ ) {
57
+ runAndroidProviderFallbackAfterFusedFailure(
58
+ locationProvider = locationProvider,
59
+ runPlatformFallback = runPlatformFallback,
60
+ failWithoutFallback = failWithoutFallback
61
+ )
62
+ }
63
+
64
+ internal fun runAndroidWatchPositionFallbackAfterFusedFailure(
65
+ locationProvider: LocationProvider?,
66
+ runPlatformFallback: () -> Unit,
67
+ failWithoutFallback: () -> Unit
68
+ ) {
69
+ runAndroidProviderFallbackAfterFusedFailure(
70
+ locationProvider = locationProvider,
71
+ runPlatformFallback = runPlatformFallback,
72
+ failWithoutFallback = failWithoutFallback
73
+ )
74
+ }