react-native-nitro-geolocation 1.1.4 → 1.2.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 (186) hide show
  1. package/README.md +74 -8
  2. package/android/build.gradle +6 -0
  3. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidAccuracy.kt +105 -0
  4. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidHeadingManager.kt +313 -0
  5. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidLocationSettings.kt +313 -0
  6. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/GetCurrentPosition.kt +46 -45
  7. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/LocationMetadata.kt +26 -0
  8. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/LocationValues.kt +31 -0
  9. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/NitroGeolocation.kt +1025 -140
  10. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/NitroGeolocationCompat.kt +11 -11
  11. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/RequestAuthorization.kt +6 -6
  12. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/WatchPosition.kt +46 -45
  13. package/ios/CLLocation+GeolocationMetadata.swift +32 -0
  14. package/ios/LocationManager.swift +205 -51
  15. package/ios/NitroGeolocation.swift +949 -110
  16. package/ios/NitroGeolocationCompat.swift +7 -7
  17. package/nitrogen/generated/android/c++/JAccuracyAuthorization.hpp +61 -0
  18. package/nitrogen/generated/android/c++/JAndroidAccuracyPreset.hpp +64 -0
  19. package/nitrogen/generated/android/c++/JAndroidGranularity.hpp +61 -0
  20. package/nitrogen/generated/android/c++/{JRNConfigurationInternal.hpp → JCompatGeolocationConfigurationInternal.hpp} +10 -10
  21. package/nitrogen/generated/android/c++/{JGeolocationError.hpp → JCompatGeolocationError.hpp} +10 -10
  22. package/nitrogen/generated/android/c++/JCompatGeolocationOptions.hpp +105 -0
  23. package/nitrogen/generated/android/c++/JCompatGeolocationResponse.hpp +67 -0
  24. package/nitrogen/generated/android/c++/JFunc_void_AccuracyAuthorization.hpp +77 -0
  25. package/nitrogen/generated/android/c++/JFunc_void_CompatGeolocationError.hpp +78 -0
  26. package/nitrogen/generated/android/c++/JFunc_void_CompatGeolocationResponse.hpp +84 -0
  27. package/nitrogen/generated/android/c++/JFunc_void_GeolocationResponse.hpp +2 -0
  28. package/nitrogen/generated/android/c++/JFunc_void_Heading.hpp +78 -0
  29. package/nitrogen/generated/android/c++/JFunc_void_LocationProviderStatus.hpp +78 -0
  30. package/nitrogen/generated/android/c++/JFunc_void_PermissionStatus.hpp +77 -0
  31. package/nitrogen/generated/android/c++/JFunc_void_std__vector_GeocodedLocation_.hpp +97 -0
  32. package/nitrogen/generated/android/c++/JFunc_void_std__vector_ReverseGeocodedAddress_.hpp +98 -0
  33. package/nitrogen/generated/android/c++/JGeocodedLocation.hpp +65 -0
  34. package/nitrogen/generated/android/c++/JGeocodingCoordinates.hpp +61 -0
  35. package/nitrogen/generated/android/c++/{JModernGeolocationConfiguration.hpp → JGeolocationConfiguration.hpp} +10 -10
  36. package/nitrogen/generated/android/c++/JGeolocationResponse.hpp +13 -3
  37. package/nitrogen/generated/android/c++/JHeading.hpp +69 -0
  38. package/nitrogen/generated/android/c++/JHeadingOptions.hpp +57 -0
  39. package/nitrogen/generated/android/c++/JHybridNitroGeolocationCompatSpec.cpp +46 -30
  40. package/nitrogen/generated/android/c++/JHybridNitroGeolocationCompatSpec.hpp +4 -4
  41. package/nitrogen/generated/android/c++/JHybridNitroGeolocationSpec.cpp +169 -33
  42. package/nitrogen/generated/android/c++/JHybridNitroGeolocationSpec.hpp +14 -3
  43. package/nitrogen/generated/android/c++/JIOSAccuracyPreset.hpp +73 -0
  44. package/nitrogen/generated/android/c++/JIOSActivityType.hpp +67 -0
  45. package/nitrogen/generated/android/c++/JLocationAccuracyOptions.hpp +65 -0
  46. package/nitrogen/generated/android/c++/JLocationAvailability.hpp +62 -0
  47. package/nitrogen/generated/android/c++/JLocationProviderStatus.hpp +77 -0
  48. package/nitrogen/generated/android/c++/JLocationProviderUsed.hpp +67 -0
  49. package/nitrogen/generated/android/c++/JLocationRequestOptions.hpp +49 -3
  50. package/nitrogen/generated/android/c++/{JGeolocationOptions.hpp → JLocationSettingsOptions.hpp} +28 -22
  51. package/nitrogen/generated/android/c++/JReverseGeocodedAddress.hpp +82 -0
  52. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/AccuracyAuthorization.kt +24 -0
  53. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/AndroidAccuracyPreset.kt +25 -0
  54. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/AndroidGranularity.kt +24 -0
  55. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/{RNConfigurationInternal.kt → CompatGeolocationConfigurationInternal.kt} +5 -5
  56. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/{GeolocationError.kt → CompatGeolocationError.kt} +5 -5
  57. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/CompatGeolocationOptions.kt +68 -0
  58. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/CompatGeolocationResponse.kt +41 -0
  59. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void_AccuracyAuthorization.kt +80 -0
  60. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/{Func_void_GeolocationError.kt → Func_void_CompatGeolocationError.kt} +9 -9
  61. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void_CompatGeolocationResponse.kt +80 -0
  62. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void_Heading.kt +80 -0
  63. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void_LocationProviderStatus.kt +80 -0
  64. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void_PermissionStatus.kt +80 -0
  65. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void_std__vector_GeocodedLocation_.kt +80 -0
  66. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void_std__vector_ReverseGeocodedAddress_.kt +80 -0
  67. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeocodedLocation.kt +44 -0
  68. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeocodingCoordinates.kt +41 -0
  69. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/{ModernGeolocationConfiguration.kt → GeolocationConfiguration.kt} +5 -5
  70. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeolocationResponse.kt +9 -3
  71. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Heading.kt +47 -0
  72. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/HeadingOptions.kt +38 -0
  73. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/HybridNitroGeolocationCompatSpec.kt +7 -7
  74. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/HybridNitroGeolocationSpec.kt +92 -3
  75. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/IOSAccuracyPreset.kt +28 -0
  76. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/IOSActivityType.kt +26 -0
  77. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/LocationAccuracyOptions.kt +41 -0
  78. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/LocationAvailability.kt +41 -0
  79. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/LocationProviderStatus.kt +53 -0
  80. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/LocationProviderUsed.kt +26 -0
  81. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/LocationRequestOptions.kt +30 -3
  82. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/{GeolocationOptions.kt → LocationSettingsOptions.kt} +11 -11
  83. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/ReverseGeocodedAddress.kt +56 -0
  84. package/nitrogen/generated/android/nitrogeolocationOnLoad.cpp +18 -4
  85. package/nitrogen/generated/ios/NitroGeolocation-Swift-Cxx-Bridge.cpp +76 -12
  86. package/nitrogen/generated/ios/NitroGeolocation-Swift-Cxx-Bridge.hpp +519 -77
  87. package/nitrogen/generated/ios/NitroGeolocation-Swift-Cxx-Umbrella.hpp +61 -12
  88. package/nitrogen/generated/ios/c++/HybridNitroGeolocationCompatSpecSwift.hpp +28 -16
  89. package/nitrogen/generated/ios/c++/HybridNitroGeolocationSpecSwift.hpp +131 -13
  90. package/nitrogen/generated/ios/swift/AccuracyAuthorization.swift +44 -0
  91. package/nitrogen/generated/ios/swift/AndroidAccuracyPreset.swift +48 -0
  92. package/nitrogen/generated/ios/swift/AndroidGranularity.swift +44 -0
  93. package/nitrogen/generated/ios/swift/{RNConfigurationInternal.swift → CompatGeolocationConfigurationInternal.swift} +5 -5
  94. package/nitrogen/generated/ios/swift/{GeolocationError.swift → CompatGeolocationError.swift} +5 -5
  95. package/nitrogen/generated/ios/swift/CompatGeolocationOptions.swift +208 -0
  96. package/nitrogen/generated/ios/swift/CompatGeolocationResponse.swift +34 -0
  97. package/nitrogen/generated/ios/swift/Func_void_AccuracyAuthorization.swift +46 -0
  98. package/nitrogen/generated/ios/swift/Func_void_CompatGeolocationError.swift +46 -0
  99. package/nitrogen/generated/ios/swift/Func_void_CompatGeolocationResponse.swift +46 -0
  100. package/nitrogen/generated/ios/swift/{Func_void_GeolocationError.swift → Func_void_Heading.swift} +11 -11
  101. package/nitrogen/generated/ios/swift/Func_void_LocationAvailability.swift +46 -0
  102. package/nitrogen/generated/ios/swift/Func_void_LocationProviderStatus.swift +46 -0
  103. package/nitrogen/generated/ios/swift/Func_void_bool.swift +46 -0
  104. package/nitrogen/generated/ios/swift/Func_void_std__vector_GeocodedLocation_.swift +46 -0
  105. package/nitrogen/generated/ios/swift/Func_void_std__vector_ReverseGeocodedAddress_.swift +46 -0
  106. package/nitrogen/generated/ios/swift/GeocodedLocation.swift +52 -0
  107. package/nitrogen/generated/ios/swift/GeocodingCoordinates.swift +34 -0
  108. package/nitrogen/generated/ios/swift/{ModernGeolocationConfiguration.swift → GeolocationConfiguration.swift} +5 -5
  109. package/nitrogen/generated/ios/swift/GeolocationResponse.swift +31 -2
  110. package/nitrogen/generated/ios/swift/Heading.swift +70 -0
  111. package/nitrogen/generated/ios/swift/HeadingOptions.swift +42 -0
  112. package/nitrogen/generated/ios/swift/HybridNitroGeolocationCompatSpec.swift +4 -4
  113. package/nitrogen/generated/ios/swift/HybridNitroGeolocationCompatSpec_cxx.swift +28 -28
  114. package/nitrogen/generated/ios/swift/HybridNitroGeolocationSpec.swift +14 -3
  115. package/nitrogen/generated/ios/swift/HybridNitroGeolocationSpec_cxx.swift +318 -15
  116. package/nitrogen/generated/ios/swift/IOSAccuracyPreset.swift +60 -0
  117. package/nitrogen/generated/ios/swift/IOSActivityType.swift +52 -0
  118. package/nitrogen/generated/ios/swift/LocationAccuracyOptions.swift +46 -0
  119. package/nitrogen/generated/ios/swift/LocationAvailability.swift +47 -0
  120. package/nitrogen/generated/ios/swift/LocationProviderStatus.swift +106 -0
  121. package/nitrogen/generated/ios/swift/LocationProviderUsed.swift +52 -0
  122. package/nitrogen/generated/ios/swift/LocationRequestOptions.swift +142 -1
  123. package/nitrogen/generated/ios/swift/{GeolocationOptions.swift → LocationSettingsOptions.swift} +39 -46
  124. package/nitrogen/generated/ios/swift/ReverseGeocodedAddress.swift +150 -0
  125. package/nitrogen/generated/shared/c++/AccuracyAuthorization.hpp +80 -0
  126. package/nitrogen/generated/shared/c++/AndroidAccuracyPreset.hpp +84 -0
  127. package/nitrogen/generated/shared/c++/AndroidGranularity.hpp +80 -0
  128. package/nitrogen/generated/shared/c++/{RNConfigurationInternal.hpp → CompatGeolocationConfigurationInternal.hpp} +11 -11
  129. package/nitrogen/generated/shared/c++/{GeolocationError.hpp → CompatGeolocationError.hpp} +11 -11
  130. package/nitrogen/generated/shared/c++/CompatGeolocationOptions.hpp +128 -0
  131. package/nitrogen/generated/shared/c++/CompatGeolocationResponse.hpp +88 -0
  132. package/nitrogen/generated/shared/c++/GeocodedLocation.hpp +91 -0
  133. package/nitrogen/generated/shared/c++/GeocodingCoordinates.hpp +87 -0
  134. package/nitrogen/generated/shared/c++/{ModernGeolocationConfiguration.hpp → GeolocationConfiguration.hpp} +11 -11
  135. package/nitrogen/generated/shared/c++/GeolocationResponse.hpp +14 -2
  136. package/nitrogen/generated/shared/c++/Heading.hpp +95 -0
  137. package/nitrogen/generated/shared/c++/HeadingOptions.hpp +83 -0
  138. package/nitrogen/generated/shared/c++/HybridNitroGeolocationCompatSpec.hpp +16 -16
  139. package/nitrogen/generated/shared/c++/HybridNitroGeolocationSpec.cpp +11 -0
  140. package/nitrogen/generated/shared/c++/HybridNitroGeolocationSpec.hpp +51 -12
  141. package/nitrogen/generated/shared/c++/IOSAccuracyPreset.hpp +96 -0
  142. package/nitrogen/generated/shared/c++/IOSActivityType.hpp +88 -0
  143. package/nitrogen/generated/shared/c++/LocationAccuracyOptions.hpp +92 -0
  144. package/nitrogen/generated/shared/c++/LocationAvailability.hpp +88 -0
  145. package/nitrogen/generated/shared/c++/LocationProviderStatus.hpp +103 -0
  146. package/nitrogen/generated/shared/c++/LocationProviderUsed.hpp +88 -0
  147. package/nitrogen/generated/shared/c++/LocationRequestOptions.hpp +47 -3
  148. package/nitrogen/generated/shared/c++/{GeolocationOptions.hpp → LocationSettingsOptions.hpp} +26 -24
  149. package/nitrogen/generated/shared/c++/ReverseGeocodedAddress.hpp +108 -0
  150. package/package.json +1 -1
  151. package/src/NitroGeolocation.nitro.ts +291 -17
  152. package/src/NitroGeolocationCompat.nitro.ts +12 -12
  153. package/src/api/geocode.ts +18 -0
  154. package/src/api/getAccuracyAuthorization.ts +12 -0
  155. package/src/api/getCurrentPosition.ts +5 -3
  156. package/src/api/getHeading.ts +13 -0
  157. package/src/api/getLastKnownPosition.ts +28 -0
  158. package/src/api/getLocationAvailability.ts +11 -0
  159. package/src/api/getProviderStatus.ts +16 -0
  160. package/src/api/hasServicesEnabled.ts +13 -0
  161. package/src/api/index.ts +11 -0
  162. package/src/api/requestLocationSettings.ts +29 -0
  163. package/src/api/requestPermission.ts +3 -1
  164. package/src/api/requestTemporaryFullAccuracy.ts +21 -0
  165. package/src/api/reverseGeocode.ts +23 -0
  166. package/src/api/setConfiguration.ts +8 -4
  167. package/src/api/watchHeading.ts +19 -0
  168. package/src/api/watchPosition.ts +2 -2
  169. package/src/compat/getCurrentPosition.ts +7 -7
  170. package/src/compat/index.tsx +5 -5
  171. package/src/compat/requestAuthorization.ts +2 -2
  172. package/src/compat/setRNConfiguration.ts +7 -5
  173. package/src/compat/watchPosition.ts +7 -7
  174. package/src/devtools/getCurrentPosition.ts +5 -3
  175. package/src/devtools/index.ts +1 -1
  176. package/src/devtools/watchPosition.ts +6 -7
  177. package/src/hooks/useWatchPosition.ts +2 -2
  178. package/src/index.tsx +35 -6
  179. package/src/publicTypes.ts +96 -0
  180. package/src/types.ts +113 -37
  181. package/src/utils/errors.test.ts +65 -0
  182. package/src/utils/errors.ts +45 -18
  183. package/src/utils/index.ts +2 -2
  184. package/src/utils/provider.test.ts +172 -1
  185. package/src/utils/provider.ts +50 -5
  186. package/nitrogen/generated/android/c++/JFunc_void_GeolocationError.hpp +0 -78
package/src/types.ts CHANGED
@@ -1,40 +1,33 @@
1
- // Public API types (compatible with @react-native-community/geolocation)
2
- export type AuthorizationLevel = "always" | "whenInUse" | "auto";
3
- export type LocationProvider = "playServices" | "android" | "auto";
1
+ // Shared Nitro schema structs. Public entry points re-export inferred aliases
2
+ // from the Nitro/Compat specs in publicTypes.ts.
3
+ export type LocationProviderUsed =
4
+ | "fused"
5
+ | "gps"
6
+ | "network"
7
+ | "passive"
8
+ | "unknown";
4
9
  export type NullableDouble = number | null;
10
+ export type AndroidAccuracyPreset = "high" | "balanced" | "low" | "passive";
11
+ export type AndroidGranularity = "permission" | "coarse" | "fine";
12
+ export type IOSAccuracyPreset =
13
+ | "bestForNavigation"
14
+ | "best"
15
+ | "nearestTenMeters"
16
+ | "hundredMeters"
17
+ | "kilometer"
18
+ | "threeKilometers"
19
+ | "reduced";
20
+ export type AccuracyAuthorization = "full" | "reduced" | "unknown";
21
+ export type IOSActivityType =
22
+ | "other"
23
+ | "automotiveNavigation"
24
+ | "fitness"
25
+ | "otherNavigation"
26
+ | "airborne";
5
27
 
6
- /**
7
- * User-facing geolocation configuration.
8
- * This uses "android" instead of "android_platform" for better DX.
9
- */
10
- export interface ModernGeolocationConfiguration {
11
- /**
12
- * Automatically request location permission when GeolocationProvider mounts.
13
- * @default false
14
- */
15
- autoRequestPermission?: boolean;
16
-
17
- /**
18
- * iOS: Authorization level
19
- */
20
- authorizationLevel?: AuthorizationLevel;
21
-
22
- /**
23
- * iOS: Enable background location updates.
24
- */
25
- enableBackgroundLocationUpdates?: boolean;
26
-
27
- /**
28
- * Android: Location provider
29
- */
30
- locationProvider?: LocationProvider;
31
- }
32
-
33
- export interface GeolocationConfiguration {
34
- skipPermissionRequests: boolean;
35
- authorizationLevel?: AuthorizationLevel;
36
- enableBackgroundLocationUpdates?: boolean;
37
- locationProvider?: LocationProvider;
28
+ export interface LocationAccuracyOptions {
29
+ android?: AndroidAccuracyPreset;
30
+ ios?: IOSAccuracyPreset;
38
31
  }
39
32
 
40
33
  export interface GeolocationCoordinates {
@@ -50,9 +43,88 @@ export interface GeolocationCoordinates {
50
43
  export interface GeolocationResponse {
51
44
  coords: GeolocationCoordinates;
52
45
  timestamp: number;
46
+ mocked?: boolean;
47
+ provider?: LocationProviderUsed;
48
+ }
49
+
50
+ export interface LocationAvailability {
51
+ available: boolean;
52
+ reason?: string;
53
+ }
54
+
55
+ export interface Heading {
56
+ magneticHeading: number;
57
+ trueHeading?: number;
58
+ accuracy?: number;
59
+ timestamp: number;
60
+ }
61
+
62
+ export interface HeadingOptions {
63
+ headingFilter?: number;
64
+ }
65
+
66
+ export interface GeocodingCoordinates {
67
+ latitude: number;
68
+ longitude: number;
69
+ }
70
+
71
+ export interface GeocodedLocation {
72
+ latitude: number;
73
+ longitude: number;
74
+ accuracy?: number;
75
+ }
76
+
77
+ export interface ReverseGeocodedAddress {
78
+ country?: string;
79
+ region?: string;
80
+ city?: string;
81
+ district?: string;
82
+ street?: string;
83
+ postalCode?: string;
84
+ formattedAddress?: string;
85
+ }
86
+
87
+ /**
88
+ * Native provider/settings status.
89
+ *
90
+ * Android includes device-level location services, provider availability, and
91
+ * Google Location Accuracy when Google Play Services exposes it.
92
+ *
93
+ * iOS includes only Core Location service availability and app background
94
+ * location mode. Android-specific provider fields are `undefined` on iOS.
95
+ */
96
+ export interface LocationProviderStatus {
97
+ /** Android system location switch, or iOS Core Location services state. */
98
+ locationServicesEnabled: boolean;
99
+
100
+ /**
101
+ * iOS: whether `UIBackgroundModes` contains `location`.
102
+ * Android: whether background location permission is granted.
103
+ */
104
+ backgroundModeEnabled: boolean;
105
+
106
+ /** Android-only GPS provider availability. Undefined on iOS. */
107
+ gpsAvailable?: boolean;
108
+
109
+ /** Android-only network provider availability. Undefined on iOS. */
110
+ networkAvailable?: boolean;
111
+
112
+ /** Android-only passive provider availability. Undefined on iOS. */
113
+ passiveAvailable?: boolean;
114
+
115
+ /**
116
+ * Android-only Google Location Accuracy state when Google Play Services
117
+ * exposes it. Undefined on iOS or when unavailable.
118
+ */
119
+ googleLocationAccuracyEnabled?: boolean;
120
+ }
121
+
122
+ export interface CompatGeolocationResponse {
123
+ coords: GeolocationCoordinates;
124
+ timestamp: number;
53
125
  }
54
126
 
55
- export interface GeolocationError {
127
+ export interface CompatGeolocationError {
56
128
  code: number;
57
129
  message: string;
58
130
  PERMISSION_DENIED: number;
@@ -60,12 +132,16 @@ export interface GeolocationError {
60
132
  TIMEOUT: number;
61
133
  }
62
134
 
63
- export interface GeolocationOptions {
135
+ export interface CompatGeolocationOptions {
64
136
  timeout?: number;
65
137
  maximumAge?: number;
66
138
  enableHighAccuracy?: boolean;
139
+ accuracy?: LocationAccuracyOptions;
67
140
  interval?: number;
68
141
  fastestInterval?: number;
69
142
  distanceFilter?: number;
70
143
  useSignificantChanges?: boolean;
144
+ activityType?: IOSActivityType;
145
+ pausesLocationUpdatesAutomatically?: boolean;
146
+ showsBackgroundLocationIndicator?: boolean;
71
147
  }
@@ -0,0 +1,65 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import {
3
+ LocationErrorCode,
4
+ createLocationError,
5
+ getLocationErrorCodeName,
6
+ mapAndroidException,
7
+ mapCLErrorCode
8
+ } from "./errors";
9
+
10
+ describe("LocationErrorCode", () => {
11
+ it("keeps legacy-compatible codes and adds modern-only error codes", () => {
12
+ expect(LocationErrorCode.INTERNAL_ERROR).toBe(-1);
13
+ expect(LocationErrorCode.PERMISSION_DENIED).toBe(1);
14
+ expect(LocationErrorCode.POSITION_UNAVAILABLE).toBe(2);
15
+ expect(LocationErrorCode.TIMEOUT).toBe(3);
16
+ expect(LocationErrorCode.PLAY_SERVICE_NOT_AVAILABLE).toBe(4);
17
+ expect(LocationErrorCode.SETTINGS_NOT_SATISFIED).toBe(5);
18
+ });
19
+
20
+ it("creates the same plain LocationError shape native sends to JS", () => {
21
+ const error = createLocationError(
22
+ LocationErrorCode.SETTINGS_NOT_SATISFIED,
23
+ "Location settings are disabled"
24
+ );
25
+
26
+ expect(error).toEqual({
27
+ code: LocationErrorCode.SETTINGS_NOT_SATISFIED,
28
+ message: "Location settings are disabled"
29
+ });
30
+ });
31
+
32
+ it("maps platform-specific error sources", () => {
33
+ expect(mapCLErrorCode(0)).toBe(LocationErrorCode.POSITION_UNAVAILABLE);
34
+ expect(mapCLErrorCode(1)).toBe(LocationErrorCode.PERMISSION_DENIED);
35
+ expect(mapAndroidException("SecurityException")).toBe(
36
+ LocationErrorCode.PERMISSION_DENIED
37
+ );
38
+ expect(mapAndroidException("ResolvableApiException")).toBe(
39
+ LocationErrorCode.SETTINGS_NOT_SATISFIED
40
+ );
41
+ expect(mapAndroidException("GooglePlayServicesNotAvailableException")).toBe(
42
+ LocationErrorCode.PLAY_SERVICE_NOT_AVAILABLE
43
+ );
44
+ });
45
+
46
+ it("returns stable names for code display", () => {
47
+ expect(getLocationErrorCodeName(LocationErrorCode.INTERNAL_ERROR)).toBe(
48
+ "INTERNAL_ERROR"
49
+ );
50
+ expect(getLocationErrorCodeName(LocationErrorCode.PERMISSION_DENIED)).toBe(
51
+ "PERMISSION_DENIED"
52
+ );
53
+ expect(
54
+ getLocationErrorCodeName(LocationErrorCode.POSITION_UNAVAILABLE)
55
+ ).toBe("POSITION_UNAVAILABLE");
56
+ expect(getLocationErrorCodeName(LocationErrorCode.TIMEOUT)).toBe("TIMEOUT");
57
+ expect(
58
+ getLocationErrorCodeName(LocationErrorCode.PLAY_SERVICE_NOT_AVAILABLE)
59
+ ).toBe("PLAY_SERVICE_NOT_AVAILABLE");
60
+ expect(
61
+ getLocationErrorCodeName(LocationErrorCode.SETTINGS_NOT_SATISFIED)
62
+ ).toBe("SETTINGS_NOT_SATISFIED");
63
+ expect(getLocationErrorCodeName(999)).toBe("UNKNOWN_LOCATION_ERROR");
64
+ });
65
+ });
@@ -1,26 +1,39 @@
1
+ import type { LocationError as NativeLocationError } from "../NitroGeolocation.nitro";
2
+
1
3
  /**
2
4
  * Error codes for geolocation errors.
3
- * These codes match the W3C Geolocation API specification.
5
+ * Codes 1-3 match the W3C Geolocation API specification. Modern API also
6
+ * exposes native location-provider/setup failures that cannot be represented
7
+ * by the legacy browser contract.
4
8
  */
5
9
  export enum LocationErrorCode {
10
+ /** Unexpected module/native failure */
11
+ INTERNAL_ERROR = -1,
6
12
  /** User denied the request for Geolocation */
7
13
  PERMISSION_DENIED = 1,
8
14
  /** Location provider is unavailable */
9
15
  POSITION_UNAVAILABLE = 2,
10
16
  /** The request to get location timed out */
11
- TIMEOUT = 3
17
+ TIMEOUT = 3,
18
+ /** Android Google Play Services provider is unavailable */
19
+ PLAY_SERVICE_NOT_AVAILABLE = 4,
20
+ /** Device/provider settings do not satisfy the request */
21
+ SETTINGS_NOT_SATISFIED = 5
12
22
  }
13
23
 
14
24
  /**
15
25
  * Geolocation error object.
16
26
  */
17
- export interface LocationError extends Error {
18
- code: LocationErrorCode;
19
- message: string;
20
- PERMISSION_DENIED: LocationErrorCode.PERMISSION_DENIED;
21
- POSITION_UNAVAILABLE: LocationErrorCode.POSITION_UNAVAILABLE;
22
- TIMEOUT: LocationErrorCode.TIMEOUT;
23
- }
27
+ export type LocationError = NativeLocationError;
28
+
29
+ const locationErrorCodeNames: Record<LocationErrorCode, string> = {
30
+ [LocationErrorCode.INTERNAL_ERROR]: "INTERNAL_ERROR",
31
+ [LocationErrorCode.PERMISSION_DENIED]: "PERMISSION_DENIED",
32
+ [LocationErrorCode.POSITION_UNAVAILABLE]: "POSITION_UNAVAILABLE",
33
+ [LocationErrorCode.TIMEOUT]: "TIMEOUT",
34
+ [LocationErrorCode.PLAY_SERVICE_NOT_AVAILABLE]: "PLAY_SERVICE_NOT_AVAILABLE",
35
+ [LocationErrorCode.SETTINGS_NOT_SATISFIED]: "SETTINGS_NOT_SATISFIED"
36
+ };
24
37
 
25
38
  /**
26
39
  * Creates a standardized LocationError object.
@@ -41,12 +54,14 @@ export function createLocationError(
41
54
  code: LocationErrorCode,
42
55
  message: string
43
56
  ): LocationError {
44
- const error = new Error(message) as LocationError;
45
- error.code = code;
46
- error.PERMISSION_DENIED = LocationErrorCode.PERMISSION_DENIED;
47
- error.POSITION_UNAVAILABLE = LocationErrorCode.POSITION_UNAVAILABLE;
48
- error.TIMEOUT = LocationErrorCode.TIMEOUT;
49
- return error;
57
+ return { code, message };
58
+ }
59
+
60
+ export function getLocationErrorCodeName(code: number): string {
61
+ return (
62
+ locationErrorCodeNames[code as LocationErrorCode] ??
63
+ "UNKNOWN_LOCATION_ERROR"
64
+ );
50
65
  }
51
66
 
52
67
  /**
@@ -59,10 +74,10 @@ export function createLocationError(
59
74
  */
60
75
  export function mapCLErrorCode(clErrorCode: number): LocationErrorCode {
61
76
  switch (clErrorCode) {
62
- case 0: // kCLErrorDenied
63
- return LocationErrorCode.PERMISSION_DENIED;
64
- case 1: // kCLErrorLocationUnknown
77
+ case 0: // kCLErrorLocationUnknown
65
78
  return LocationErrorCode.POSITION_UNAVAILABLE;
79
+ case 1: // kCLErrorDenied
80
+ return LocationErrorCode.PERMISSION_DENIED;
66
81
  default:
67
82
  return LocationErrorCode.POSITION_UNAVAILABLE;
68
83
  }
@@ -78,5 +93,17 @@ export function mapAndroidException(exceptionType: string): LocationErrorCode {
78
93
  if (exceptionType === "SecurityException") {
79
94
  return LocationErrorCode.PERMISSION_DENIED;
80
95
  }
96
+ if (
97
+ exceptionType === "GooglePlayServicesNotAvailableException" ||
98
+ exceptionType === "GooglePlayServicesRepairableException"
99
+ ) {
100
+ return LocationErrorCode.PLAY_SERVICE_NOT_AVAILABLE;
101
+ }
102
+ if (
103
+ exceptionType === "ResolvableApiException" ||
104
+ exceptionType === "LocationSettingsException"
105
+ ) {
106
+ return LocationErrorCode.SETTINGS_NOT_SATISFIED;
107
+ }
81
108
  return LocationErrorCode.POSITION_UNAVAILABLE;
82
109
  }
@@ -7,9 +7,9 @@ export { isCachedLocationValid } from "./cache";
7
7
  export {
8
8
  LocationErrorCode,
9
9
  createLocationError,
10
+ getLocationErrorCodeName,
10
11
  mapCLErrorCode,
11
- mapAndroidException,
12
- type LocationError
12
+ mapAndroidException
13
13
  } from "./errors";
14
14
  export {
15
15
  isBetterLocation,
@@ -1,5 +1,78 @@
1
1
  import { describe, expect, it } from "vitest";
2
- import { selectProviderForAndroidPermissions } from "./provider";
2
+ import {
3
+ getAndroidProviderOrder,
4
+ resolveAndroidAccuracy,
5
+ selectProviderForAndroidPermissions
6
+ } from "./provider";
7
+
8
+ describe("resolveAndroidAccuracy", () => {
9
+ it("keeps enableHighAccuracy as the legacy default", () => {
10
+ expect(resolveAndroidAccuracy(undefined, true)).toEqual({
11
+ mode: "high",
12
+ explicitPreset: undefined
13
+ });
14
+
15
+ expect(resolveAndroidAccuracy(undefined, false)).toEqual({
16
+ mode: "balanced",
17
+ explicitPreset: undefined
18
+ });
19
+ });
20
+
21
+ it("lets explicit Android accuracy override enableHighAccuracy", () => {
22
+ expect(resolveAndroidAccuracy({ android: "high" }, false)).toEqual({
23
+ mode: "high",
24
+ explicitPreset: "high"
25
+ });
26
+
27
+ expect(resolveAndroidAccuracy({ android: "low" }, true)).toEqual({
28
+ mode: "low",
29
+ explicitPreset: "low"
30
+ });
31
+ });
32
+
33
+ it("ignores iOS-only accuracy presets on Android", () => {
34
+ expect(resolveAndroidAccuracy({ ios: "bestForNavigation" }, false)).toEqual(
35
+ {
36
+ mode: "balanced",
37
+ explicitPreset: undefined
38
+ }
39
+ );
40
+ });
41
+ });
42
+
43
+ describe("getAndroidProviderOrder", () => {
44
+ it("keeps GPS fallback only for legacy balanced mode", () => {
45
+ expect(
46
+ getAndroidProviderOrder({
47
+ mode: "balanced",
48
+ explicitPreset: undefined
49
+ })
50
+ ).toEqual(["network", "gps"]);
51
+
52
+ expect(
53
+ getAndroidProviderOrder({
54
+ mode: "balanced",
55
+ explicitPreset: "balanced"
56
+ })
57
+ ).toEqual(["network"]);
58
+ });
59
+
60
+ it("keeps low accuracy network-first and passive accuracy passive-only", () => {
61
+ expect(
62
+ getAndroidProviderOrder({
63
+ mode: "low",
64
+ explicitPreset: "low"
65
+ })
66
+ ).toEqual(["network", "passive"]);
67
+
68
+ expect(
69
+ getAndroidProviderOrder({
70
+ mode: "passive",
71
+ explicitPreset: "passive"
72
+ })
73
+ ).toEqual(["passive"]);
74
+ });
75
+ });
3
76
 
4
77
  describe("selectProviderForAndroidPermissions", () => {
5
78
  it("prefers the network provider for low-accuracy coarse-only requests", () => {
@@ -98,6 +171,104 @@ describe("selectProviderForAndroidPermissions", () => {
98
171
  ).toBe("gps");
99
172
  });
100
173
 
174
+ it("lets explicit high accuracy override enableHighAccuracy=false", () => {
175
+ expect(
176
+ selectProviderForAndroidPermissions({
177
+ enableHighAccuracy: false,
178
+ accuracy: {
179
+ android: "high"
180
+ },
181
+ providers: {
182
+ gps: true,
183
+ network: true
184
+ },
185
+ permissions: {
186
+ fine: true,
187
+ coarse: true
188
+ }
189
+ })
190
+ ).toBe("gps");
191
+ });
192
+
193
+ it("does not fall back to GPS for explicit balanced accuracy", () => {
194
+ expect(
195
+ selectProviderForAndroidPermissions({
196
+ enableHighAccuracy: true,
197
+ accuracy: {
198
+ android: "balanced"
199
+ },
200
+ providers: {
201
+ gps: true,
202
+ network: false
203
+ },
204
+ permissions: {
205
+ fine: true,
206
+ coarse: true
207
+ }
208
+ })
209
+ ).toBeNull();
210
+ });
211
+
212
+ it("does not fall back to GPS for explicit low accuracy", () => {
213
+ expect(
214
+ selectProviderForAndroidPermissions({
215
+ enableHighAccuracy: true,
216
+ accuracy: {
217
+ android: "low"
218
+ },
219
+ providers: {
220
+ gps: true,
221
+ network: false,
222
+ passive: false
223
+ },
224
+ permissions: {
225
+ fine: true,
226
+ coarse: true
227
+ }
228
+ })
229
+ ).toBeNull();
230
+ });
231
+
232
+ it("uses passive provider only for explicit passive accuracy", () => {
233
+ expect(
234
+ selectProviderForAndroidPermissions({
235
+ enableHighAccuracy: true,
236
+ accuracy: {
237
+ android: "passive"
238
+ },
239
+ providers: {
240
+ gps: true,
241
+ network: true,
242
+ passive: true
243
+ },
244
+ permissions: {
245
+ fine: true,
246
+ coarse: true
247
+ }
248
+ })
249
+ ).toBe("passive");
250
+ });
251
+
252
+ it("rejects passive accuracy when the passive provider is disabled", () => {
253
+ expect(
254
+ selectProviderForAndroidPermissions({
255
+ enableHighAccuracy: false,
256
+ accuracy: {
257
+ android: "passive"
258
+ },
259
+ providers: {
260
+ gps: true,
261
+ network: true,
262
+ passive: false
263
+ },
264
+ permissions: {
265
+ fine: true,
266
+ coarse: true
267
+ }
268
+ })
269
+ ).toBeNull();
270
+ });
271
+
101
272
  it("rejects provider selection when no Android location permission is granted", () => {
102
273
  expect(
103
274
  selectProviderForAndroidPermissions({
@@ -1,13 +1,23 @@
1
+ import type { AndroidAccuracyPreset, LocationAccuracyOptions } from "../types";
2
+
1
3
  /**
2
4
  * Location provider types supported on Android.
3
5
  */
4
- export type Provider = "gps" | "network" | null;
6
+ export type Provider = "gps" | "network" | "passive" | null;
7
+ export type AndroidAccuracyMode = AndroidAccuracyPreset;
8
+
9
+ export interface AndroidAccuracyResolution {
10
+ mode: AndroidAccuracyMode;
11
+ explicitPreset?: AndroidAccuracyPreset;
12
+ }
5
13
 
6
14
  export interface AndroidProviderSelectionInput {
7
15
  enableHighAccuracy: boolean;
16
+ accuracy?: LocationAccuracyOptions;
8
17
  providers: {
9
18
  gps: boolean;
10
19
  network: boolean;
20
+ passive?: boolean;
11
21
  };
12
22
  permissions: {
13
23
  fine: boolean;
@@ -72,14 +82,49 @@ export function selectProvider(
72
82
  return null;
73
83
  }
74
84
 
85
+ export function resolveAndroidAccuracy(
86
+ accuracy: LocationAccuracyOptions | undefined,
87
+ enableHighAccuracy: boolean
88
+ ): AndroidAccuracyResolution {
89
+ const preset = accuracy?.android;
90
+
91
+ return {
92
+ mode: preset ?? (enableHighAccuracy ? "high" : "balanced"),
93
+ explicitPreset: preset
94
+ };
95
+ }
96
+
97
+ export function getAndroidProviderOrder({
98
+ mode,
99
+ explicitPreset
100
+ }: AndroidAccuracyResolution): Exclude<Provider, null>[] {
101
+ switch (mode) {
102
+ case "high":
103
+ return ["gps", "network"];
104
+ case "balanced":
105
+ return explicitPreset ? ["network"] : ["network", "gps"];
106
+ case "low":
107
+ return ["network", "passive"];
108
+ case "passive":
109
+ return ["passive"];
110
+ }
111
+ }
112
+
75
113
  export function selectProviderForAndroidPermissions({
76
114
  enableHighAccuracy,
115
+ accuracy,
77
116
  providers,
78
117
  permissions
79
118
  }: AndroidProviderSelectionInput): Provider {
80
- const gpsAvailable = providers.gps && permissions.fine;
81
- const networkAvailable =
82
- providers.network && (permissions.coarse || permissions.fine);
119
+ const providerOrder = getAndroidProviderOrder(
120
+ resolveAndroidAccuracy(accuracy, enableHighAccuracy)
121
+ );
83
122
 
84
- return selectProvider(enableHighAccuracy, gpsAvailable, networkAvailable);
123
+ return (
124
+ providerOrder.find((provider) => {
125
+ if (!providers[provider]) return false;
126
+ if (provider === "gps") return permissions.fine;
127
+ return permissions.coarse || permissions.fine;
128
+ }) ?? null
129
+ );
85
130
  }
@@ -1,78 +0,0 @@
1
- ///
2
- /// JFunc_void_GeolocationError.hpp
3
- /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
- /// https://github.com/mrousavy/nitro
5
- /// Copyright © Marc Rousavy @ Margelo
6
- ///
7
-
8
- #pragma once
9
-
10
- #include <fbjni/fbjni.h>
11
- #include <functional>
12
-
13
- #include "GeolocationError.hpp"
14
- #include <functional>
15
- #include <NitroModules/JNICallable.hpp>
16
- #include "JGeolocationError.hpp"
17
- #include <string>
18
-
19
- namespace margelo::nitro::nitrogeolocation {
20
-
21
- using namespace facebook;
22
-
23
- /**
24
- * Represents the Java/Kotlin callback `(error: GeolocationError) -> Unit`.
25
- * This can be passed around between C++ and Java/Kotlin.
26
- */
27
- struct JFunc_void_GeolocationError: public jni::JavaClass<JFunc_void_GeolocationError> {
28
- public:
29
- static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/nitrogeolocation/Func_void_GeolocationError;";
30
-
31
- public:
32
- /**
33
- * Invokes the function this `JFunc_void_GeolocationError` instance holds through JNI.
34
- */
35
- void invoke(const GeolocationError& error) const {
36
- static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JGeolocationError> /* error */)>("invoke");
37
- method(self(), JGeolocationError::fromCpp(error));
38
- }
39
- };
40
-
41
- /**
42
- * An implementation of Func_void_GeolocationError that is backed by a C++ implementation (using `std::function<...>`)
43
- */
44
- class JFunc_void_GeolocationError_cxx final: public jni::HybridClass<JFunc_void_GeolocationError_cxx, JFunc_void_GeolocationError> {
45
- public:
46
- static jni::local_ref<JFunc_void_GeolocationError::javaobject> fromCpp(const std::function<void(const GeolocationError& /* error */)>& func) {
47
- return JFunc_void_GeolocationError_cxx::newObjectCxxArgs(func);
48
- }
49
-
50
- public:
51
- /**
52
- * Invokes the C++ `std::function<...>` this `JFunc_void_GeolocationError_cxx` instance holds.
53
- */
54
- void invoke_cxx(jni::alias_ref<JGeolocationError> error) {
55
- _func(error->toCpp());
56
- }
57
-
58
- public:
59
- [[nodiscard]]
60
- inline const std::function<void(const GeolocationError& /* error */)>& getFunction() const {
61
- return _func;
62
- }
63
-
64
- public:
65
- static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/nitrogeolocation/Func_void_GeolocationError_cxx;";
66
- static void registerNatives() {
67
- registerHybrid({makeNativeMethod("invoke_cxx", JFunc_void_GeolocationError_cxx::invoke_cxx)});
68
- }
69
-
70
- private:
71
- explicit JFunc_void_GeolocationError_cxx(const std::function<void(const GeolocationError& /* error */)>& func): _func(func) { }
72
-
73
- private:
74
- friend HybridBase;
75
- std::function<void(const GeolocationError& /* error */)> _func;
76
- };
77
-
78
- } // namespace margelo::nitro::nitrogeolocation