From 8782272b21564e3670f2bd8c9e27ba27f46a7cc5 Mon Sep 17 00:00:00 2001 From: Joonas Kerttula Date: Mon, 2 Jun 2025 15:43:52 +0300 Subject: [PATCH 1/5] feat!: support new React Native architecture --- .github/ISSUE_TEMPLATE/bug_report.yml | 15 +- .github/workflows/ci.yml | 24 +- .gitignore | 4 +- .npmignore | 3 +- .nvmrc | 2 +- .tool-versions | 2 +- .watchmanconfig | 4 +- .yarnrc.yml | 4 +- ANDROIDAUTO.md | 31 +- CARPLAY.md | 29 +- CONTRIBUTING.md | 14 + README.md | 55 +- android/build.gradle | 124 +- .../viewmanagers/NavViewManagerDelegate.java | 149 + .../viewmanagers/NavViewManagerInterface.java | 69 + .../rn/navsdk/NativeNavAutoModuleSpec.java | 163 + .../rn/navsdk/NativeNavModuleSpec.java | 201 + .../rn/navsdk/NativeNavViewModuleSpec.java | 123 + android/generated/jni/CMakeLists.txt | 36 + .../jni/RNNavigationSdkSpec-generated.cpp | 487 ++ android/generated/jni/RNNavigationSdkSpec.h | 63 + .../ComponentDescriptors.cpp | 36 + .../ComponentDescriptors.h | 40 + .../RNNavigationSdkSpec/EventEmitters.cpp | 201 + .../RNNavigationSdkSpec/EventEmitters.h | 157 + .../components/RNNavigationSdkSpec/Props.cpp | 73 + .../components/RNNavigationSdkSpec/Props.h | 162 + .../RNNavigationSdkSpecJSI-generated.cpp | 539 ++ .../RNNavigationSdkSpecJSI.h | 2864 +++++++ .../RNNavigationSdkSpec/ShadowNodes.cpp | 31 + .../RNNavigationSdkSpec/ShadowNodes.h | 48 + .../components/RNNavigationSdkSpec/States.cpp | 30 + .../components/RNNavigationSdkSpec/States.h | 45 + android/gradle.properties | 6 + android/src/main/AndroidManifest.xml | 19 +- .../src/main/AndroidManifestNew.xml | 19 +- .../google/android/react/navsdk/Command.java | 83 - .../react/navsdk/INavigationViewCallback.java | 41 - .../google/android/react/navsdk/JsErrors.java | 24 - .../react/navsdk/MapViewController.java | 578 -- .../android/react/navsdk/NavViewManager.java | 410 - .../android/react/navsdk/NavViewModule.java | 251 - .../google/android/react/navsdk/Package.java | 45 - .../rn/navsdk/GMNAndroidAutoBaseScreen.java} | 62 +- .../maps/android/rn/navsdk/GMNCircle.java | 23 + .../android/rn/navsdk/GMNCollectionUtil.java} | 10 +- .../maps/android/rn/navsdk/GMNColorUtil.java | 62 + .../android/rn/navsdk/GMNConstants.java} | 6 +- .../android/rn/navsdk/GMNCustomTypes.java} | 6 +- .../rn/navsdk/GMNEnumTranslationUtil.java} | 90 +- .../android/rn/navsdk/GMNGroundOverlay.java | 23 + .../maps/android/rn/navsdk/GMNJsErrors.java | 41 + .../maps/android/rn/navsdk/GMNJsonUtils.java | 37 + .../rn/navsdk/GMNMapViewController.java | 664 ++ .../rn/navsdk/GMNMapViewFragment.java} | 114 +- .../android/rn/navsdk/GMNMapViewLayout.java | 624 ++ .../maps/android/rn/navsdk/GMNMarker.java | 23 + .../android/rn/navsdk/GMNNavAutoModule.java} | 345 +- .../rn/navsdk/GMNNavForwardingManager.java} | 10 +- .../navsdk/GMNNavInfoReceivingService.java} | 4 +- .../android/rn/navsdk/GMNNavModule.java} | 436 +- .../maps/android/rn/navsdk/GMNNavPackage.kt | 84 + .../rn/navsdk/GMNNavViewFragment.java} | 148 +- .../android/rn/navsdk/GMNNavViewManager.java | 377 + .../android/rn/navsdk/GMNNavViewModule.java | 378 + .../rn/navsdk/GMNObjectTranslationUtil.java} | 107 +- .../maps/android/rn/navsdk/GMNPolygon.java | 23 + .../maps/android/rn/navsdk/GMNPolyline.java | 23 + .../rn/navsdk/GMNStylingOptionsBuilder.java} | 21 +- .../maps/android/rn/navsdk/GMNViewProps.java | 128 + .../rn/navsdk/IGMNMapViewCallback.java | 34 + .../rn/navsdk/IGMNMapViewFragment.java} | 12 +- .../rn/navsdk/IGMNNavViewFragment.java} | 6 +- .../navsdk/IGMNNavigationAutoCallback.java} | 4 +- .../rn/navsdk/IGMNNavigationCallback.java} | 4 +- .../rn/navsdk/IGMNNavigationViewCallback.java | 20 + .../navsdk/IGMNNavigationViewController.java} | 4 +- .../src/main/res/layout/fragment_nav_view.xml | 32 - app.json | 4 - babel.config.js | 2 +- example/.detoxrc.js | 11 +- example/.watchmanconfig | 1 + example/Gemfile | 3 +- example/Gemfile.lock | 120 + example/README.md | 2 +- example/android/app/build.gradle | 29 +- .../android/rn/navsdkexample}/DetoxTest.java | 4 +- .../android/app/src/debug/AndroidManifest.xml | 13 +- .../android/app/src/main/AndroidManifest.xml | 4 +- .../android/rn/navsdkexample/MainActivity.kt | 38 + .../rn/navsdkexample/MainApplication.kt | 60 + .../rn/navsdkexample/ManeuverConverter.kt | 303 + .../navsdkexample/SampleAndroidAutoScreen.kt | 149 + .../SampleAndroidAutoService.kt} | 26 +- .../navsdkexample/SampleAndroidAutoSession.kt | 100 + .../main/java/com/sampleapp/MainActivity.java | 48 - .../java/com/sampleapp/MainApplication.java | 85 - .../java/com/sampleapp/ManeuverConverter.java | 265 - .../sampleapp/SampleAndroidAutoScreen.java | 150 - .../sampleapp/SampleAndroidAutoSession.java | 114 - .../res/drawable/rn_edit_text_material.xml | 3 +- .../app/src/main/res/values/strings.xml | 8 +- .../app/src/main/res/values/styles.xml | 4 +- .../src/main/res/xml/automotive_app_desc.xml | 2 +- example/android/build.gradle | 14 +- example/android/gradle.properties | 8 +- .../android/gradle/wrapper/gradle-wrapper.jar | Bin 61574 -> 43583 bytes .../gradle/wrapper/gradle-wrapper.properties | 2 +- example/android/gradlew | 5 +- example/android/settings.gradle | 2 +- example/app.json | 4 +- example/babel.config.js | 53 +- example/index.ts | 4 +- ...elegateCarPlay.m => AppDelegateCarPlay.mm} | 2 +- example/ios/Podfile | 33 +- .../project.pbxproj | 346 +- .../ReactNativeNavigationSdkExample.xcscheme} | 32 +- ...ativeNavigationSdkExampleCarPlay.xcscheme} | 63 +- .../contents.xcworkspacedata | 10 + .../xcshareddata/IDEWorkspaceChecks.plist | 0 .../xcshareddata/WorkspaceSettings.xcsettings | 5 + .../AppDelegate.h | 0 .../AppDelegate.mm} | 5 +- .../AppDelegateCarPlay.h | 0 .../AppDelegateCarPlay.mm | 83 + .../CarSceneDelegate.h | 0 .../CarSceneDelegate.mm} | 0 .../AppIcon.appiconset/Contents.json | 0 .../Images.xcassets/Contents.json | 6 + .../circle.imageset/Contents.json | 0 .../circle.imageset/circle.png | Bin .../Info-CarPlay.plist | 0 .../Info.plist | 0 .../Keys.plist.sample | 0 .../LaunchScreen.storyboard | 20 +- .../PhoneSceneDelegate.h | 0 .../PhoneSceneDelegate.mm} | 0 .../PrivacyInfo.xcprivacy | 0 ...ctNativeNavigationSdkExample.entitlements} | 0 .../main.mm} | 6 +- .../ReactNativeNavigationSdkExampleTests.m} | 39 +- .../contents.xcworkspacedata | 7 - .../contents.xcworkspacedata | 10 - .../SampleApp/Images.xcassets/Contents.json | 6 - example/jest.config.js | 4 +- example/metro.config.js | 43 +- example/package.json | 45 +- example/react-native.config.js | 15 +- example/src/App.tsx | 3 +- example/src/controls/mapNavControlsReducer.ts | 181 + example/src/controls/mapsControls.tsx | 439 +- example/src/controls/navigationControls.tsx | 259 +- .../src/screens/IntegrationTestsScreen.tsx | 135 +- example/src/screens/MultipleMapsScreen.tsx | 319 +- example/src/screens/NavigationScreen.tsx | 377 +- .../integration_tests/integration_test.ts | 708 +- .../src/screens/integration_tests/utils.ts | 39 +- example/src/styles.ts | 1 - .../BaseCarSceneDelegate.h | 5 + ...ceneDelegate.m => BaseCarSceneDelegate.mm} | 9 +- .../CustomTypes.h | 0 ios/FabricObjectTranslationUtil.h | 64 + .../INavigationCallback.h | 9 +- .../INavigationViewCallback.h | 5 +- .../NavAutoModule.h | 9 +- ios/NavAutoModule.mm | 525 ++ .../NavModule.h | 12 +- .../NavModule.m => NavModule.mm} | 836 ++- .../NavEventDispatcher.h => NavView.h} | 27 +- ios/NavView.mm | 337 + .../NavViewController.h | 56 +- ...vViewController.m => NavViewController.mm} | 268 +- .../NavViewModule.h | 14 +- ios/NavViewModule.mm | 517 ++ ios/ObjectTranslationUtil.h | 96 + ios/ObjectTranslationUtil.mm | 439 ++ .../ComponentDescriptors.cpp | 36 + .../ComponentDescriptors.h | 42 + .../RNNavigationSdkSpec/EventEmitters.cpp | 201 + .../RNNavigationSdkSpec/EventEmitters.h | 152 + ios/generated/RNNavigationSdkSpec/Props.cpp | 73 + ios/generated/RNNavigationSdkSpec/Props.h | 171 + .../RCTComponentViewHelpers.h | 37 + .../RNNavigationSdkSpec-generated.mm | 1077 +++ .../RNNavigationSdkSpec/RNNavigationSdkSpec.h | 1419 ++++ .../RNNavigationSdkSpec/ShadowNodes.cpp | 31 + .../RNNavigationSdkSpec/ShadowNodes.h | 47 + ios/generated/RNNavigationSdkSpec/States.cpp | 30 + ios/generated/RNNavigationSdkSpec/States.h | 44 + .../RNNavigationSdkSpecJSI-generated.cpp | 539 ++ ios/generated/RNNavigationSdkSpecJSI.h | 3346 +++++++++ .../project.pbxproj | 387 - .../NavAutoEventDispatcher.m | 65 - .../NavAutoModule.m | 425 -- .../NavEventDispatcher.m | 77 - ios/react-native-navigation-sdk/NavView.h | 41 - ios/react-native-navigation-sdk/NavView.m | 121 - .../NavViewModule.m | 211 - .../ObjectTranslationUtil.h | 36 - .../ObjectTranslationUtil.m | 246 - .../RCTNavViewManager.m | 442 -- .../UIColor+Util.m | 71 - jsdoc.json | 19 - lefthook.yml | 3 + package.json | 97 +- react-native-navigation-sdk.podspec | 31 +- .../UIColor+Util.h => react-native.config.js | 27 +- scripts/format-java.sh | 2 + scripts/format-kotlin.sh | 18 + scripts/format-objc.sh | 6 +- scripts/format.sh | 17 + src/auto/types.ts | 25 +- src/auto/useNavigationAuto.ts | 331 +- src/{index.ts => index.tsx} | 0 src/maps/mapView/mapView.tsx | 168 +- src/maps/mapView/mapViewController.ts | 169 +- src/maps/mapView/types.ts | 263 +- src/maps/types.ts | 45 +- src/native/NativeNavAutoModule.ts | 139 + src/native/NativeNavModule.ts | 198 + src/native/NativeNavViewComponent.ts | 168 + src/native/NativeNavViewModule.ts | 121 + src/native/index.ts | 29 + .../navigation/NavigationProvider.tsx | 32 +- src/navigation/navigation/types.ts | 193 +- .../navigation/useNavigationController.ts | 362 +- .../navigationView/navigationView.tsx | 211 +- .../navigationViewController.ts | 51 +- src/navigation/navigationView/types.ts | 118 +- src/navigation/types.ts | 6 +- src/shared/index.ts | 4 +- src/shared/types.ts | 147 + src/shared/useModuleListeners.ts | 126 - .../shared/useNativeEventCallback.ts | 26 +- .../shared/viewIdUtil.ts | 29 +- src/shared/viewManager.ts | 73 - tsconfig.build.json | 2 +- tsconfig.json | 12 +- turbo.json | 2 + yarn.lock | 6629 ++++++----------- 240 files changed, 25675 insertions(+), 12989 deletions(-) create mode 100644 android/generated/java/com/facebook/react/viewmanagers/NavViewManagerDelegate.java create mode 100644 android/generated/java/com/facebook/react/viewmanagers/NavViewManagerInterface.java create mode 100644 android/generated/java/com/google/maps/android/rn/navsdk/NativeNavAutoModuleSpec.java create mode 100644 android/generated/java/com/google/maps/android/rn/navsdk/NativeNavModuleSpec.java create mode 100644 android/generated/java/com/google/maps/android/rn/navsdk/NativeNavViewModuleSpec.java create mode 100644 android/generated/jni/CMakeLists.txt create mode 100644 android/generated/jni/RNNavigationSdkSpec-generated.cpp create mode 100644 android/generated/jni/RNNavigationSdkSpec.h create mode 100644 android/generated/jni/react/renderer/components/RNNavigationSdkSpec/ComponentDescriptors.cpp create mode 100644 android/generated/jni/react/renderer/components/RNNavigationSdkSpec/ComponentDescriptors.h create mode 100644 android/generated/jni/react/renderer/components/RNNavigationSdkSpec/EventEmitters.cpp create mode 100644 android/generated/jni/react/renderer/components/RNNavigationSdkSpec/EventEmitters.h create mode 100644 android/generated/jni/react/renderer/components/RNNavigationSdkSpec/Props.cpp create mode 100644 android/generated/jni/react/renderer/components/RNNavigationSdkSpec/Props.h create mode 100644 android/generated/jni/react/renderer/components/RNNavigationSdkSpec/RNNavigationSdkSpecJSI-generated.cpp create mode 100644 android/generated/jni/react/renderer/components/RNNavigationSdkSpec/RNNavigationSdkSpecJSI.h create mode 100644 android/generated/jni/react/renderer/components/RNNavigationSdkSpec/ShadowNodes.cpp create mode 100644 android/generated/jni/react/renderer/components/RNNavigationSdkSpec/ShadowNodes.h create mode 100644 android/generated/jni/react/renderer/components/RNNavigationSdkSpec/States.cpp create mode 100644 android/generated/jni/react/renderer/components/RNNavigationSdkSpec/States.h create mode 100644 android/gradle.properties rename ios/react-native-navigation-sdk.xcodeproj/project.xcworkspace/contents.xcworkspacedata => android/src/main/AndroidManifestNew.xml (69%) delete mode 100644 android/src/main/java/com/google/android/react/navsdk/Command.java delete mode 100644 android/src/main/java/com/google/android/react/navsdk/INavigationViewCallback.java delete mode 100644 android/src/main/java/com/google/android/react/navsdk/JsErrors.java delete mode 100644 android/src/main/java/com/google/android/react/navsdk/MapViewController.java delete mode 100644 android/src/main/java/com/google/android/react/navsdk/NavViewManager.java delete mode 100644 android/src/main/java/com/google/android/react/navsdk/NavViewModule.java delete mode 100644 android/src/main/java/com/google/android/react/navsdk/Package.java rename android/src/main/java/com/google/{android/react/navsdk/AndroidAutoBaseScreen.java => maps/android/rn/navsdk/GMNAndroidAutoBaseScreen.java} (82%) create mode 100644 android/src/main/java/com/google/maps/android/rn/navsdk/GMNCircle.java rename android/src/main/java/com/google/{android/react/navsdk/CollectionUtil.java => maps/android/rn/navsdk/GMNCollectionUtil.java} (84%) create mode 100644 android/src/main/java/com/google/maps/android/rn/navsdk/GMNColorUtil.java rename android/src/main/java/com/google/{android/react/navsdk/Constants.java => maps/android/rn/navsdk/GMNConstants.java} (75%) rename android/src/main/java/com/google/{android/react/navsdk/CustomTypes.java => maps/android/rn/navsdk/GMNCustomTypes.java} (86%) rename android/src/main/java/com/google/{android/react/navsdk/EnumTranslationUtil.java => maps/android/rn/navsdk/GMNEnumTranslationUtil.java} (51%) create mode 100644 android/src/main/java/com/google/maps/android/rn/navsdk/GMNGroundOverlay.java create mode 100644 android/src/main/java/com/google/maps/android/rn/navsdk/GMNJsErrors.java create mode 100644 android/src/main/java/com/google/maps/android/rn/navsdk/GMNJsonUtils.java create mode 100644 android/src/main/java/com/google/maps/android/rn/navsdk/GMNMapViewController.java rename android/src/main/java/com/google/{android/react/navsdk/MapViewFragment.java => maps/android/rn/navsdk/GMNMapViewFragment.java} (57%) create mode 100644 android/src/main/java/com/google/maps/android/rn/navsdk/GMNMapViewLayout.java create mode 100644 android/src/main/java/com/google/maps/android/rn/navsdk/GMNMarker.java rename android/src/main/java/com/google/{android/react/navsdk/NavAutoModule.java => maps/android/rn/navsdk/GMNNavAutoModule.java} (54%) rename android/src/main/java/com/google/{android/react/navsdk/NavForwardingManager.java => maps/android/rn/navsdk/GMNNavForwardingManager.java} (85%) rename android/src/main/java/com/google/{android/react/navsdk/NavInfoReceivingService.java => maps/android/rn/navsdk/GMNNavInfoReceivingService.java} (96%) rename android/src/main/java/com/google/{android/react/navsdk/NavModule.java => maps/android/rn/navsdk/GMNNavModule.java} (65%) create mode 100644 android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavPackage.kt rename android/src/main/java/com/google/{android/react/navsdk/NavViewFragment.java => maps/android/rn/navsdk/GMNNavViewFragment.java} (50%) create mode 100644 android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavViewManager.java create mode 100644 android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavViewModule.java rename android/src/main/java/com/google/{android/react/navsdk/ObjectTranslationUtil.java => maps/android/rn/navsdk/GMNObjectTranslationUtil.java} (69%) create mode 100644 android/src/main/java/com/google/maps/android/rn/navsdk/GMNPolygon.java create mode 100644 android/src/main/java/com/google/maps/android/rn/navsdk/GMNPolyline.java rename android/src/main/java/com/google/{android/react/navsdk/StylingOptionsBuilder.java => maps/android/rn/navsdk/GMNStylingOptionsBuilder.java} (84%) create mode 100644 android/src/main/java/com/google/maps/android/rn/navsdk/GMNViewProps.java create mode 100644 android/src/main/java/com/google/maps/android/rn/navsdk/IGMNMapViewCallback.java rename android/src/main/java/com/google/{android/react/navsdk/IMapViewFragment.java => maps/android/rn/navsdk/IGMNMapViewFragment.java} (77%) rename android/src/main/java/com/google/{android/react/navsdk/INavViewFragment.java => maps/android/rn/navsdk/IGMNNavViewFragment.java} (86%) rename android/src/main/java/com/google/{android/react/navsdk/INavigationAutoCallback.java => maps/android/rn/navsdk/IGMNNavigationAutoCallback.java} (88%) rename android/src/main/java/com/google/{android/react/navsdk/INavigationCallback.java => maps/android/rn/navsdk/IGMNNavigationCallback.java} (88%) create mode 100644 android/src/main/java/com/google/maps/android/rn/navsdk/IGMNNavigationViewCallback.java rename android/src/main/java/com/google/{android/react/navsdk/INavigationViewController.java => maps/android/rn/navsdk/IGMNNavigationViewController.java} (88%) delete mode 100644 android/src/main/res/layout/fragment_nav_view.xml delete mode 100644 app.json create mode 100644 example/.watchmanconfig create mode 100644 example/Gemfile.lock rename example/android/app/src/androidTest/java/com/{sampleapp => google/maps/android/rn/navsdkexample}/DetoxTest.java (96%) create mode 100644 example/android/app/src/main/java/com/google/maps/android/rn/navsdkexample/MainActivity.kt create mode 100644 example/android/app/src/main/java/com/google/maps/android/rn/navsdkexample/MainApplication.kt create mode 100644 example/android/app/src/main/java/com/google/maps/android/rn/navsdkexample/ManeuverConverter.kt create mode 100644 example/android/app/src/main/java/com/google/maps/android/rn/navsdkexample/SampleAndroidAutoScreen.kt rename example/android/app/src/main/java/com/{sampleapp/SampleAndroidAutoService.java => google/maps/android/rn/navsdkexample/SampleAndroidAutoService.kt} (54%) create mode 100644 example/android/app/src/main/java/com/google/maps/android/rn/navsdkexample/SampleAndroidAutoSession.kt delete mode 100644 example/android/app/src/main/java/com/sampleapp/MainActivity.java delete mode 100644 example/android/app/src/main/java/com/sampleapp/MainApplication.java delete mode 100644 example/android/app/src/main/java/com/sampleapp/ManeuverConverter.java delete mode 100644 example/android/app/src/main/java/com/sampleapp/SampleAndroidAutoScreen.java delete mode 100644 example/android/app/src/main/java/com/sampleapp/SampleAndroidAutoSession.java rename example/ios/{SampleApp/AppDelegateCarPlay.m => AppDelegateCarPlay.mm} (98%) rename example/ios/{SampleApp.xcodeproj => ReactNativeNavigationSdkExample.xcodeproj}/project.pbxproj (62%) rename example/ios/{SampleApp.xcodeproj/xcshareddata/xcschemes/SampleApp.xcscheme => ReactNativeNavigationSdkExample.xcodeproj/xcshareddata/xcschemes/ReactNativeNavigationSdkExample.xcscheme} (64%) rename example/ios/{SampleApp.xcodeproj/xcshareddata/xcschemes/SampleAppCarPlay.xcscheme => ReactNativeNavigationSdkExample.xcodeproj/xcshareddata/xcschemes/ReactNativeNavigationSdkExampleCarPlay.xcscheme} (58%) create mode 100644 example/ios/ReactNativeNavigationSdkExample.xcworkspace/contents.xcworkspacedata rename example/ios/{SampleApp.xcworkspace => ReactNativeNavigationSdkExample.xcworkspace}/xcshareddata/IDEWorkspaceChecks.plist (100%) create mode 100644 example/ios/ReactNativeNavigationSdkExample.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings rename example/ios/{SampleApp => ReactNativeNavigationSdkExample}/AppDelegate.h (100%) rename example/ios/{SampleApp/AppDelegate.m => ReactNativeNavigationSdkExample/AppDelegate.mm} (91%) rename example/ios/{SampleApp => ReactNativeNavigationSdkExample}/AppDelegateCarPlay.h (100%) create mode 100644 example/ios/ReactNativeNavigationSdkExample/AppDelegateCarPlay.mm rename example/ios/{SampleApp => ReactNativeNavigationSdkExample}/CarSceneDelegate.h (100%) rename example/ios/{SampleApp/CarSceneDelegate.m => ReactNativeNavigationSdkExample/CarSceneDelegate.mm} (100%) rename example/ios/{SampleApp => ReactNativeNavigationSdkExample}/Images.xcassets/AppIcon.appiconset/Contents.json (100%) create mode 100644 example/ios/ReactNativeNavigationSdkExample/Images.xcassets/Contents.json rename example/ios/{SampleApp => ReactNativeNavigationSdkExample}/Images.xcassets/circle.imageset/Contents.json (100%) rename example/ios/{SampleApp => ReactNativeNavigationSdkExample}/Images.xcassets/circle.imageset/circle.png (100%) rename example/ios/{SampleApp => ReactNativeNavigationSdkExample}/Info-CarPlay.plist (100%) rename example/ios/{SampleApp => ReactNativeNavigationSdkExample}/Info.plist (100%) rename example/ios/{SampleApp => ReactNativeNavigationSdkExample}/Keys.plist.sample (100%) rename example/ios/{SampleApp => ReactNativeNavigationSdkExample}/LaunchScreen.storyboard (73%) rename example/ios/{SampleApp => ReactNativeNavigationSdkExample}/PhoneSceneDelegate.h (100%) rename example/ios/{SampleApp/PhoneSceneDelegate.m => ReactNativeNavigationSdkExample/PhoneSceneDelegate.mm} (100%) rename example/ios/{SampleApp => ReactNativeNavigationSdkExample}/PrivacyInfo.xcprivacy (100%) rename example/ios/{SampleApp/SampleApp.entitlements => ReactNativeNavigationSdkExample/ReactNativeNavigationSdkExample.entitlements} (100%) rename example/ios/{SampleApp/main.m => ReactNativeNavigationSdkExample/main.mm} (76%) rename example/ios/{SampleAppTests/SampleAppTests.m => ReactNativeNavigationSdkExampleTests/ReactNativeNavigationSdkExampleTests.m} (63%) delete mode 100644 example/ios/SampleApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 example/ios/SampleApp.xcworkspace/contents.xcworkspacedata delete mode 100644 example/ios/SampleApp/Images.xcassets/Contents.json create mode 100644 example/src/controls/mapNavControlsReducer.ts rename ios/{react-native-navigation-sdk => }/BaseCarSceneDelegate.h (92%) rename ios/{react-native-navigation-sdk/BaseCarSceneDelegate.m => BaseCarSceneDelegate.mm} (94%) rename ios/{react-native-navigation-sdk => }/CustomTypes.h (100%) create mode 100644 ios/FabricObjectTranslationUtil.h rename ios/{react-native-navigation-sdk => }/INavigationCallback.h (90%) rename ios/{react-native-navigation-sdk => }/INavigationViewCallback.h (88%) rename ios/{react-native-navigation-sdk => }/NavAutoModule.h (84%) create mode 100644 ios/NavAutoModule.mm rename ios/{react-native-navigation-sdk => }/NavModule.h (76%) rename ios/{react-native-navigation-sdk/NavModule.m => NavModule.mm} (50%) rename ios/{react-native-navigation-sdk/NavEventDispatcher.h => NavView.h} (54%) create mode 100644 ios/NavView.mm rename ios/{react-native-navigation-sdk => }/NavViewController.h (62%) rename ios/{react-native-navigation-sdk/NavViewController.m => NavViewController.mm} (63%) rename ios/{react-native-navigation-sdk => }/NavViewModule.h (68%) create mode 100644 ios/NavViewModule.mm create mode 100644 ios/ObjectTranslationUtil.h create mode 100644 ios/ObjectTranslationUtil.mm create mode 100644 ios/generated/RNNavigationSdkSpec/ComponentDescriptors.cpp create mode 100644 ios/generated/RNNavigationSdkSpec/ComponentDescriptors.h create mode 100644 ios/generated/RNNavigationSdkSpec/EventEmitters.cpp create mode 100644 ios/generated/RNNavigationSdkSpec/EventEmitters.h create mode 100644 ios/generated/RNNavigationSdkSpec/Props.cpp create mode 100644 ios/generated/RNNavigationSdkSpec/Props.h create mode 100644 ios/generated/RNNavigationSdkSpec/RCTComponentViewHelpers.h create mode 100644 ios/generated/RNNavigationSdkSpec/RNNavigationSdkSpec-generated.mm create mode 100644 ios/generated/RNNavigationSdkSpec/RNNavigationSdkSpec.h create mode 100644 ios/generated/RNNavigationSdkSpec/ShadowNodes.cpp create mode 100644 ios/generated/RNNavigationSdkSpec/ShadowNodes.h create mode 100644 ios/generated/RNNavigationSdkSpec/States.cpp create mode 100644 ios/generated/RNNavigationSdkSpec/States.h create mode 100644 ios/generated/RNNavigationSdkSpecJSI-generated.cpp create mode 100644 ios/generated/RNNavigationSdkSpecJSI.h delete mode 100644 ios/react-native-navigation-sdk.xcodeproj/project.pbxproj delete mode 100644 ios/react-native-navigation-sdk/NavAutoEventDispatcher.m delete mode 100644 ios/react-native-navigation-sdk/NavAutoModule.m delete mode 100644 ios/react-native-navigation-sdk/NavEventDispatcher.m delete mode 100644 ios/react-native-navigation-sdk/NavView.h delete mode 100644 ios/react-native-navigation-sdk/NavView.m delete mode 100644 ios/react-native-navigation-sdk/NavViewModule.m delete mode 100644 ios/react-native-navigation-sdk/ObjectTranslationUtil.h delete mode 100644 ios/react-native-navigation-sdk/ObjectTranslationUtil.m delete mode 100644 ios/react-native-navigation-sdk/RCTNavViewManager.m delete mode 100644 ios/react-native-navigation-sdk/UIColor+Util.m delete mode 100644 jsdoc.json rename ios/react-native-navigation-sdk/UIColor+Util.h => react-native.config.js (62%) create mode 100755 scripts/format-kotlin.sh create mode 100755 scripts/format.sh rename src/{index.ts => index.tsx} (100%) create mode 100644 src/native/NativeNavAutoModule.ts create mode 100644 src/native/NativeNavModule.ts create mode 100644 src/native/NativeNavViewComponent.ts create mode 100644 src/native/NativeNavViewModule.ts create mode 100644 src/native/index.ts delete mode 100644 src/shared/useModuleListeners.ts rename ios/react-native-navigation-sdk/RCTNavViewManager.h => src/shared/useNativeEventCallback.ts (60%) rename ios/react-native-navigation-sdk/NavAutoEventDispatcher.h => src/shared/viewIdUtil.ts (53%) delete mode 100644 src/shared/viewManager.ts diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 3bda0a4a..f4e73731 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -60,7 +60,16 @@ body: attributes: label: React Native Doctor Output description: | - Run `npx react-native doctor` in your projectq and paste the output below. + Run `npx react-native doctor` in your project folder and paste the output below. + render: shell + validations: + required: true + - type: textarea + attributes: + label: React Native Info Output + description: | + Run `npx react-native info` in your project folder and paste the output below. + render: shell validations: required: true - type: textarea @@ -96,9 +105,13 @@ body: Without this we will unlikely be able to progress on the issue, as we need to be able to reproduce the problem locally. value: | +
Code sample + ```javascript // Example code here ``` + +
validations: required: true - type: textarea diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 71493de3..6051d6b2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,7 @@ jobs: run: yarn lint - name: Typecheck files - run: yarn test:types + run: yarn typecheck check-objc-formatting: runs-on: ubuntu-latest @@ -52,7 +52,7 @@ jobs: - name: Check Objective-C formatting run: ./scripts/format-objc.sh --check - check-java-formatting: + check-java-and-kotlin-formatting: runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -84,6 +84,24 @@ jobs: - name: Check Java formatting run: ./scripts/format-java.sh --check + - name: Download ktfmt + run: | + KTFMT_VERSION=0.54 + KTFMT_URL=https://repo1.maven.org/maven2/com/facebook/ktfmt/${KTFMT_VERSION}/ktfmt-${KTFMT_VERSION}-jar-with-dependencies.jar + mkdir -p $HOME/ktfmt + curl -L -o $HOME/ktfmt/ktfmt.jar $KTFMT_URL + + - name: Create ktfmt wrapper script + run: | + cat << 'EOF' > /usr/local/bin/ktfmt + #!/bin/sh + exec java -jar "$HOME/ktfmt/ktfmt.jar" "$@" + EOF + chmod +x /usr/local/bin/ktfmt + + - name: Check Kotlin formatting + run: ./scripts/format-kotlin.sh --check + test: runs-on: ubuntu-latest timeout-minutes: 30 @@ -222,7 +240,7 @@ jobs: NO_FLIPPER: 1 - name: Copy Keys.plist file from sample - run: cp example/ios/SampleApp/Keys.plist.sample example/ios/SampleApp/Keys.plist + run: cp example/ios/ReactNativeNavigationSdkExample/Keys.plist.sample example/ios/ReactNativeNavigationSdkExample/Keys.plist - name: Build example for iOS run: | diff --git a/.gitignore b/.gitignore index b002a8ab..e88aa9c7 100644 --- a/.gitignore +++ b/.gitignore @@ -28,7 +28,7 @@ DerivedData *.ipa *.xcuserstate project.xcworkspace -.xcode.env.local +**/.xcode.env.local Keys.plist # Android/IJ @@ -81,5 +81,5 @@ android/keystores/debug.keystore # generated by bob lib/ -# tests +# Tests coverage/ diff --git a/.npmignore b/.npmignore index ad9bfc9e..37d63714 100644 --- a/.npmignore +++ b/.npmignore @@ -1,3 +1,4 @@ example coverage -node_modules \ No newline at end of file +node_modules +scripts \ No newline at end of file diff --git a/.nvmrc b/.nvmrc index 3f430af8..9a2a0e21 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v18 +v20 diff --git a/.tool-versions b/.tool-versions index 6df261ca..4b8ef84e 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1 +1 @@ -nodejs 18.20.1 +nodejs 20.18.3 diff --git a/.watchmanconfig b/.watchmanconfig index 1a1d1f31..0967ef42 100644 --- a/.watchmanconfig +++ b/.watchmanconfig @@ -1,3 +1 @@ -{ - "fsevents_latency": 0.1 -} +{} diff --git a/.yarnrc.yml b/.yarnrc.yml index dab182ef..a0e015ca 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -17,8 +17,8 @@ nmHoistingLimits: workspaces plugins: - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs - spec: "@yarnpkg/plugin-interactive-tools" + spec: '@yarnpkg/plugin-interactive-tools' - path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs - spec: "@yarnpkg/plugin-workspace-tools" + spec: '@yarnpkg/plugin-workspace-tools' yarnPath: .yarn/releases/yarn-3.6.1.cjs diff --git a/ANDROIDAUTO.md b/ANDROIDAUTO.md index e7d32028..1f05fe5f 100644 --- a/ANDROIDAUTO.md +++ b/ANDROIDAUTO.md @@ -20,7 +20,7 @@ For all the steps above, you can refer to the Android example application for gu ### Screen for Android Auto -Once your project is configured accordingly, and you are ready to build the screen for Android Auto, you can leverage the `AndroidAutoBaseScreen` provided by the SDK. This base class simplifies the setup by handling initialization, teardown, and rendering the map on the Android Auto display. +Once your project is configured accordingly, and you are ready to build the screen for Android Auto, you can leverage the `GMNAndroidAutoBaseScreen` provided by the SDK. This base class simplifies the setup by handling initialization, teardown, and rendering the map on the Android Auto display. Please refer to the `SampleAndroidAutoScreen.java` file in the Android example app for guidance. @@ -61,7 +61,7 @@ public Template onGetTemplate() { } ``` -For advanced customization, you can bypass the base class and implement your own screen by inheriting `Screen`. You can use the provided `AndroidAutoBaseScreen` base class as a reference on how to do that. +For advanced customization, you can bypass the base class and implement your own screen by inheriting `Screen`. You can use the provided `GMNAndroidAutoBaseScreen` base class as a reference on how to do that. ### React Native specific setup @@ -70,22 +70,25 @@ On the React Native side, you can use the `useNavigationAuto` hook to interface ```tsx const { mapViewAutoController, - addListeners: addAutoListener, - removeListeners: removeAutoListeners, } = useNavigationAuto(); -const navigationAutoCallbacks: NavigationAutoCallbacks = useMemo( - () => ({ - onCustomNavigationAutoEvent: (event: CustomNavigationAutoEvent) => { - console.log('onCustomNavigationAutoEvent:', event); - }, - onAutoScreenAvailabilityChanged: (available: boolean) => { +useEffect(() => { + mapViewAutoController.setOnAutoScreenAvailabilityChangedListener( + (available: boolean) => { console.log('onAutoScreenAvailabilityChanged:', available); setMapViewAutoAvailable(available); - }, - }), - [] -); + } + ); + mapViewAutoController.setOnCustomNavigationAutoEventListener( + (event: CustomNavigationAutoEvent) => { + console.log('onCustomNavigationAutoEvent:', event); + } + ); + + return () => { + mapViewAutoController.removeAllListeners(); + }; +}); const setMapType = (mapType: MapType) => { console.log('setMapType', mapType); diff --git a/CARPLAY.md b/CARPLAY.md index 40e1f067..75f566dd 100644 --- a/CARPLAY.md +++ b/CARPLAY.md @@ -56,22 +56,25 @@ On the React Native side, you can use the `useNavigationAuto` hook to interface ```tsx const { mapViewAutoController, - addListeners: addAutoListener, - removeListeners: removeAutoListeners, } = useNavigationAuto(); -const navigationAutoCallbacks: NavigationAutoCallbacks = useMemo( - () => ({ - onCustomNavigationAutoEvent: (event: CustomNavigationAutoEvent) => { - console.log('onCustomNavigationAutoEvent:', event); - }, - onAutoScreenAvailabilityChanged: (available: boolean) => { +useEffect(() => { + mapViewAutoController.setOnAutoScreenAvailabilityChangedListener( + (available: boolean) => { console.log('onAutoScreenAvailabilityChanged:', available); setMapViewAutoAvailable(available); - }, - }), - [] -); + } + ); + mapViewAutoController.setOnCustomNavigationAutoEventListener( + (event: CustomNavigationAutoEvent) => { + console.log('onCustomNavigationAutoEvent:', event); + } + ); + + return () => { + mapViewAutoController.removeAllListeners(); + }; +}); const setMapType = (mapType: MapType) => { console.log('setMapType', mapType); @@ -83,4 +86,4 @@ For a more detailed example, refer to the `NavigationScreen.tsx` in the React Na ## Example Project -For a fully functional CarPlay implementation, check out the [SampleApp](./example/ios/) Xcode project, which includes the `SampleAppCarPlay` build target. The sample already contains test entitlement so you don't need to request one from Apple to run it. +For a fully functional CarPlay implementation, check out the [SampleApp](./example/ios/) Xcode project, which includes the `ReactNativeNavigationSdkExampleCarPlay` build target. The sample already contains test entitlement so you don't need to request one from Apple to run it. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9a382f0e..7329150d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,6 +31,7 @@ This project follows - [addlicense](https://github.com/google/addlicense) - [google-java-format Version 1.23.0](https://github.com/google/google-java-format) (used to format Java code). - [clang-format](https://clang.llvm.org/docs/ClangFormat.html) (used to format Objective-C code). +- [ktfmt](https://facebook.github.io/ktfmt/) (used to format Kotlin code). ## 2. Forking & cloning the repository @@ -97,6 +98,18 @@ This script will format all Objective-C files under the /ios and /example/ios di ``` This script will format all Java files under the /android and /example/android directories according to Google's Java style guide. +**Kotlin:** +```bash +./scripts/format-kotlin.sh +``` +This script will format all Kotlin files under the /android and /example/android directories according to Google's Kotlin style guide. + +**All:** +```bash +./scripts/format.sh +``` +This script run all above formatters. + ## 5. Code reviews @@ -140,6 +153,7 @@ yarn run example detox:test:ios-release ``` Android: +Create AVD emulator with the name "Pixel_9_Pro_API_35" and run the command below. ```bash yarn run example detox:test:android-release ``` diff --git a/README.md b/README.md index 4b52519d..b3a6a672 100644 --- a/README.md +++ b/README.md @@ -15,12 +15,13 @@ This repository contains a React Native plugin that provides a [Google Navigatio | | Android | iOS | | ------------------------------- | ------- | --------- | -| **Minimum mobile OS supported** | SDK 23+ | iOS 15.0+ | +| **Minimum mobile OS supported** | SDK 23+ | iOS 16.0+ | -* A React Native project +* Supported React Native version: **0.78+** + * See [React Native Support](#react-native-support) below for version and architecture requirements * A Google Cloud project - * If you are a Mobility Services developer, you must contact Sales as described in [Mobility services documentation](https://developers.google.com/maps/documentation/transportation-logistics/mobility). - * If you are not a Mobility Services developer, refer to [Setup Google Cloud Project](https://developers.google.com/maps/documentation/navigation/android-sdk/cloud-setup) for instructions. + * If you are a Mobility Services developer, you must contact Sales as described in [Mobility services documentation](https://developers.google.com/maps/documentation/transportation-logistics/mobility). + * If you are not a Mobility Services developer, refer to [Setup Google Cloud Project](https://developers.google.com/maps/documentation/navigation/android-sdk/cloud-setup) for instructions. * An [API key](https://console.cloud.google.com/google/maps-apis/credentials) from the project above * The API key must be configured for both Android and iOS. Refer to [Android Using Api Keys](https://developers.google.com/maps/documentation/navigation/android-sdk/get-api-key) and [iOS Using Api Keys](https://developers.google.com/maps/documentation/navigation/ios-sdk/get-api-key) respectively for instructions. * If targeting Android, [Google Play Services](https://developers.google.com/android/guides/overview) installed and enabled @@ -45,14 +46,6 @@ import { NavigationView } from '@googlemaps/react-native-navigation-sdk'; ### Android -#### Disable new architecture - -This package does not yet support new architecture. Make sure new architecture is disabled in your `android/gradle.properties` file: - -```groovy -newArchEnabled=false -``` - #### Enable Jetifier To ensure compatibility with AndroidX, enable Jetifier in your `android/gradle.properties` file: @@ -100,14 +93,6 @@ See example configuration for secrets plugin at example applications [build.grad ### iOS -#### Disable new architecture - -This package does not yet support new architecture. Make sure new architecture is disabled in your `ios/Podfile`: - -```ruby -ENV['RCT_NEW_ARCH_ENABLED'] = '0' -``` - #### Set Google Maps API Key To set up, specify your API key in the application delegate `ios/Runner/AppDelegate.m`: @@ -179,7 +164,7 @@ const { navigationController } = useNavigation(); const initializeNavigation = useCallback(async () => { try { - await navigationController.init(); + const status: NavigationInitializationStatus = await navigationController.init(); console.log('Navigation initialized'); } catch (error) { console.error('Error initializing navigation', error); @@ -361,6 +346,34 @@ This package uses the Google Maps [Navigation SDK](https://mapsplatform.google.c > [!NOTE] > This package provides a `MapView` component, which can be used as a classic Google Maps view without navigation. See [Add a map view](#add-a-map-view) for details. +## React Native Support + +> [!IMPORTANT] +> **This package is tested and supported only with React Native versions 0.78 and above, and requires the New Architecture (Fabric and TurboModules) to be enabled.** +> +> If you are using an older version of React Native (below 0.78) or cannot have the New Architecture enabled, you must use version `0.9.3` or earlier of this package. + +The New Architecture is enabled by default from React Native 0.76 onwards, but you should verify it is enabled in your project. See below for instructions. + +#### Enabling New Architecture + +**Android:** +Add the following to your `android/gradle.properties` file: +```groovy +newArchEnabled=true +``` + +**iOS:** +Add the following to your `ios/Podfile` file: +```ruby +ENV['RCT_NEW_ARCH_ENABLED'] = '1' +``` + +If you need to use the legacy React Native architecture or an older React Native version, install version `0.9.3` or earlier: +```shell +npm i @googlemaps/react-native-navigation-sdk@0.9.3 +``` + ## Contributing See the [Contributing guide](./CONTRIBUTING.md). diff --git a/android/build.gradle b/android/build.gradle index a0376cd9..2a655fd1 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -12,58 +12,90 @@ // See the License for the specific language governing permissions and // limitations under the License. -import groovy.json.JsonSlurper - buildscript { - ext.kotlin_version = '2.0.0' - repositories { - google() - mavenCentral() - } + ext.getExtOrDefault = {name -> + return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['react_native_navigation_sdk_' + name] + } - dependencies { - classpath("com.android.tools.build:gradle:8.4.0") - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } + repositories { + google() + mavenCentral() + } + + dependencies { + classpath "com.android.tools.build:gradle:8.7.2" + // noinspection DifferentKotlinGradleVersion + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}" + } } def isNewArchitectureEnabled() { return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true" } -apply plugin: 'com.android.library' +apply plugin: "com.android.library" +apply plugin: "kotlin-android" if (isNewArchitectureEnabled()) { apply plugin: "com.facebook.react" } +def getExtOrIntegerDefault(name) { + return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["react_native_navigation_sdk_" + name]).toInteger() +} + +def supportsNamespace() { + def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.') + def major = parsed[0].toInteger() + def minor = parsed[1].toInteger() + + // Namespace support was added in 7.3.0 + return (major == 7 && minor >= 3) || major >= 8 +} + android { - namespace "com.google.android.react.navsdk" - compileSdkVersion 34 + if (supportsNamespace()) { + namespace "com.google.maps.android.rn.navsdk" - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceSets { + main { + manifest.srcFile "src/main/AndroidManifestNew.xml" + } } + } - defaultConfig { - minSdkVersion 24 - targetSdkVersion 34 - versionCode 1 - // get version name from package.json version - versionName "1.0" - } + compileSdkVersion getExtOrIntegerDefault("compileSdkVersion") + + defaultConfig { + minSdkVersion getExtOrIntegerDefault("minSdkVersion") + targetSdkVersion getExtOrIntegerDefault("targetSdkVersion") + buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() + } + + buildFeatures { + buildConfig true + } - buildTypes { - release { - minifyEnabled true - } + buildTypes { + release { + minifyEnabled false } + } - lintOptions { - abortOnError false - disable "GradleCompatible" + lintOptions { + disable "GradleCompatible" + } + + sourceSets { + main { + if (isNewArchitectureEnabled()) { + java.srcDirs += [ + "generated/java", + "generated/jni" + ] + } } + } } repositories { @@ -71,11 +103,29 @@ repositories { mavenCentral() } +def kotlin_version = getExtOrDefault("kotlinVersion") +def nav_sdk_version = getExtOrDefault("navSdkVersion") + dependencies { - implementation "androidx.car.app:app:1.4.0" - implementation "androidx.car.app:app-projected:1.4.0" - implementation 'com.facebook.react:react-native:+' - implementation 'androidx.constraintlayout:constraintlayout:2.1.4' - implementation "com.google.android.libraries.navigation:navigation:6.1.0" - api 'com.google.guava:guava:31.0.1-android' + implementation "com.facebook.react:react-android" + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + + // Android Auto libraries + implementation 'androidx.car.app:app:1.4.0' + implementation 'androidx.car.app:app-projected:1.4.0' + + // Navigation SDK library + implementation "com.google.android.libraries.navigation:navigation:$nav_sdk_version" + + // Support libraries + implementation 'com.google.code.gson:gson:2.12.1' + api 'com.google.guava:guava:31.0.1-android' +} + +if (isNewArchitectureEnabled()) { + react { + jsRootDir = file("../src/") + libraryName = "ReactNativeNavigationSdk" + codegenJavaPackageName = "com.google.maps.android.rn.navsdk" + } } diff --git a/android/generated/java/com/facebook/react/viewmanagers/NavViewManagerDelegate.java b/android/generated/java/com/facebook/react/viewmanagers/NavViewManagerDelegate.java new file mode 100644 index 00000000..a825cffd --- /dev/null +++ b/android/generated/java/com/facebook/react/viewmanagers/NavViewManagerDelegate.java @@ -0,0 +1,149 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). +* +* Do not edit this file as changes may cause incorrect behavior and will be lost +* once the code is regenerated. +* +* @generated by codegen project: GeneratePropsJavaDelegate.js +*/ + +package com.facebook.react.viewmanagers; + +import android.view.View; +import androidx.annotation.Nullable; +import com.facebook.react.bridge.DynamicFromObject; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.uimanager.BaseViewManager; +import com.facebook.react.uimanager.BaseViewManagerDelegate; +import com.facebook.react.uimanager.LayoutShadowNode; + +public class NavViewManagerDelegate & NavViewManagerInterface> extends BaseViewManagerDelegate { + public NavViewManagerDelegate(U viewManager) { + super(viewManager); + } + @Override + public void setProperty(T view, String propName, @Nullable Object value) { + switch (propName) { + case "viewType": + mViewManager.setViewType(view, value == null ? 0 : ((Double) value).intValue()); + break; + case "nativeID": + mViewManager.setNativeID(view, value == null ? null : (String) value); + break; + case "mapId": + mViewManager.setMapId(view, value == null ? null : (String) value); + break; + case "mapType": + mViewManager.setMapType(view, value == null ? 1 : ((Double) value).intValue()); + break; + case "mapPadding": + mViewManager.setMapPadding(view, (ReadableMap) value); + break; + case "navigationUIEnabled": + mViewManager.setNavigationUIEnabled(view, value == null ? null : (Boolean) value); + break; + case "tripProgressBarEnabled": + mViewManager.setTripProgressBarEnabled(view, value == null ? false : (boolean) value); + break; + case "trafficIncidentsCardEnabled": + mViewManager.setTrafficIncidentsCardEnabled(view, value == null ? true : (boolean) value); + break; + case "headerEnabled": + mViewManager.setHeaderEnabled(view, value == null ? true : (boolean) value); + break; + case "footerEnabled": + mViewManager.setFooterEnabled(view, value == null ? true : (boolean) value); + break; + case "speedometerEnabled": + mViewManager.setSpeedometerEnabled(view, value == null ? true : (boolean) value); + break; + case "speedLimitIconEnabled": + mViewManager.setSpeedLimitIconEnabled(view, value == null ? true : (boolean) value); + break; + case "recenterButtonEnabled": + mViewManager.setRecenterButtonEnabled(view, value == null ? true : (boolean) value); + break; + case "navigationViewStylingOptions": + mViewManager.setNavigationViewStylingOptions(view, new DynamicFromObject(value)); + break; + case "nightMode": + mViewManager.setNightMode(view, value == null ? 0 : ((Double) value).intValue()); + break; + case "followingPerspective": + mViewManager.setFollowingPerspective(view, value == null ? 0 : ((Double) value).intValue()); + break; + case "mapStyle": + mViewManager.setMapStyle(view, value == null ? null : (String) value); + break; + case "mapToolbarEnabled": + mViewManager.setMapToolbarEnabled(view, value == null ? true : (boolean) value); + break; + case "indoorEnabled": + mViewManager.setIndoorEnabled(view, value == null ? true : (boolean) value); + break; + case "trafficEnabled": + mViewManager.setTrafficEnabled(view, value == null ? false : (boolean) value); + break; + case "compassEnabled": + mViewManager.setCompassEnabled(view, value == null ? true : (boolean) value); + break; + case "myLocationButtonEnabled": + mViewManager.setMyLocationButtonEnabled(view, value == null ? true : (boolean) value); + break; + case "myLocationEnabled": + mViewManager.setMyLocationEnabled(view, value == null ? false : (boolean) value); + break; + case "rotateGesturesEnabled": + mViewManager.setRotateGesturesEnabled(view, value == null ? true : (boolean) value); + break; + case "scrollGesturesEnabled": + mViewManager.setScrollGesturesEnabled(view, value == null ? true : (boolean) value); + break; + case "scrollGesturesEnabledDuringRotateOrZoom": + mViewManager.setScrollGesturesEnabledDuringRotateOrZoom(view, value == null ? true : (boolean) value); + break; + case "tiltGesturesEnabled": + mViewManager.setTiltGesturesEnabled(view, value == null ? true : (boolean) value); + break; + case "zoomControlsEnabled": + mViewManager.setZoomControlsEnabled(view, value == null ? true : (boolean) value); + break; + case "zoomGesturesEnabled": + mViewManager.setZoomGesturesEnabled(view, value == null ? true : (boolean) value); + break; + case "buildingsEnabled": + mViewManager.setBuildingsEnabled(view, value == null ? true : (boolean) value); + break; + case "reportIncidentButtonEnabled": + mViewManager.setReportIncidentButtonEnabled(view, value == null ? true : (boolean) value); + break; + case "minZoomLevel": + mViewManager.setMinZoomLevel(view, value == null ? null : ((Double) value).floatValue()); + break; + case "maxZoomLevel": + mViewManager.setMaxZoomLevel(view, value == null ? null : ((Double) value).floatValue()); + break; + case "initialCameraPosition": + mViewManager.setInitialCameraPosition(view, (ReadableMap) value); + break; + default: + super.setProperty(view, propName, value); + } + } +} diff --git a/android/generated/java/com/facebook/react/viewmanagers/NavViewManagerInterface.java b/android/generated/java/com/facebook/react/viewmanagers/NavViewManagerInterface.java new file mode 100644 index 00000000..4d33bcfc --- /dev/null +++ b/android/generated/java/com/facebook/react/viewmanagers/NavViewManagerInterface.java @@ -0,0 +1,69 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). +* +* Do not edit this file as changes may cause incorrect behavior and will be lost +* once the code is regenerated. +* +* @generated by codegen project: GeneratePropsJavaInterface.js +*/ + +package com.facebook.react.viewmanagers; + +import android.view.View; +import androidx.annotation.Nullable; +import com.facebook.react.bridge.Dynamic; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.uimanager.ViewManagerWithGeneratedInterface; + +public interface NavViewManagerInterface extends ViewManagerWithGeneratedInterface { + void setViewType(T view, int value); + void setNativeID(T view, @Nullable String value); + void setMapId(T view, @Nullable String value); + void setMapType(T view, int value); + void setMapPadding(T view, @Nullable ReadableMap value); + void setNavigationUIEnabled(T view, @Nullable Boolean value); + void setTripProgressBarEnabled(T view, boolean value); + void setTrafficIncidentsCardEnabled(T view, boolean value); + void setHeaderEnabled(T view, boolean value); + void setFooterEnabled(T view, boolean value); + void setSpeedometerEnabled(T view, boolean value); + void setSpeedLimitIconEnabled(T view, boolean value); + void setRecenterButtonEnabled(T view, boolean value); + void setNavigationViewStylingOptions(T view, Dynamic value); + void setNightMode(T view, int value); + void setFollowingPerspective(T view, int value); + void setMapStyle(T view, @Nullable String value); + void setMapToolbarEnabled(T view, boolean value); + void setIndoorEnabled(T view, boolean value); + void setTrafficEnabled(T view, boolean value); + void setCompassEnabled(T view, boolean value); + void setMyLocationButtonEnabled(T view, boolean value); + void setMyLocationEnabled(T view, boolean value); + void setRotateGesturesEnabled(T view, boolean value); + void setScrollGesturesEnabled(T view, boolean value); + void setScrollGesturesEnabledDuringRotateOrZoom(T view, boolean value); + void setTiltGesturesEnabled(T view, boolean value); + void setZoomControlsEnabled(T view, boolean value); + void setZoomGesturesEnabled(T view, boolean value); + void setBuildingsEnabled(T view, boolean value); + void setReportIncidentButtonEnabled(T view, boolean value); + void setMinZoomLevel(T view, @Nullable Float value); + void setMaxZoomLevel(T view, @Nullable Float value); + void setInitialCameraPosition(T view, @Nullable ReadableMap value); +} diff --git a/android/generated/java/com/google/maps/android/rn/navsdk/NativeNavAutoModuleSpec.java b/android/generated/java/com/google/maps/android/rn/navsdk/NativeNavAutoModuleSpec.java new file mode 100644 index 00000000..373a6270 --- /dev/null +++ b/android/generated/java/com/google/maps/android/rn/navsdk/NativeNavAutoModuleSpec.java @@ -0,0 +1,163 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateModuleJavaSpec.js + * + * @nolint + */ + +package com.google.maps.android.rn.navsdk; + +import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.turbomodule.core.interfaces.TurboModule; +import javax.annotation.Nonnull; + +public abstract class NativeNavAutoModuleSpec extends ReactContextBaseJavaModule implements TurboModule { + public static final String NAME = "NavAutoModule"; + + public NativeNavAutoModuleSpec(ReactApplicationContext reactContext) { + super(reactContext); + } + + @Override + public @Nonnull String getName() { + return NAME; + } + + protected final void emitOnAutoScreenAvailabilityChanged(boolean value) { + mEventEmitterCallback.invoke("onAutoScreenAvailabilityChanged", value); + } + + protected final void emitOnCustomNavigationAutoEvent(ReadableMap value) { + mEventEmitterCallback.invoke("onCustomNavigationAutoEvent", value); + } + + @ReactMethod + @DoNotStrip + public abstract void isAutoScreenAvailable(Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void setMapType(double mapType); + + @ReactMethod + @DoNotStrip + public abstract void setMapStyle(String mapStyle); + + @ReactMethod + @DoNotStrip + public abstract void clearMapView(Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void addCircle(ReadableMap options, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void addMarker(ReadableMap options, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void addPolyline(ReadableMap options, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void addPolygon(ReadableMap options, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void addGroundOverlay(ReadableMap options, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void moveCamera(ReadableMap cameraPosition, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void removeMarker(String id, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void removePolyline(String id, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void removePolygon(String id, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void removeCircle(String id, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void removeGroundOverlay(String id, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void setIndoorEnabled(boolean isOn); + + @ReactMethod + @DoNotStrip + public abstract void setTrafficEnabled(boolean isOn); + + @ReactMethod + @DoNotStrip + public abstract void setCompassEnabled(boolean isOn); + + @ReactMethod + @DoNotStrip + public abstract void setMyLocationEnabled(boolean isOn); + + @ReactMethod + @DoNotStrip + public abstract void setBuildingsEnabled(boolean isOn); + + @ReactMethod + @DoNotStrip + public abstract void setZoomLevel(double zoomLevel, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void setMapPadding(double top, double left, double bottom, double right); + + @ReactMethod + @DoNotStrip + public abstract void getCameraPosition(Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void getMyLocation(Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void getUiSettings(Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void isMyLocationEnabled(Promise promise); +} diff --git a/android/generated/java/com/google/maps/android/rn/navsdk/NativeNavModuleSpec.java b/android/generated/java/com/google/maps/android/rn/navsdk/NativeNavModuleSpec.java new file mode 100644 index 00000000..a99fbf0c --- /dev/null +++ b/android/generated/java/com/google/maps/android/rn/navsdk/NativeNavModuleSpec.java @@ -0,0 +1,201 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateModuleJavaSpec.js + * + * @nolint + */ + +package com.google.maps.android.rn.navsdk; + +import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.turbomodule.core.interfaces.TurboModule; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public abstract class NativeNavModuleSpec extends ReactContextBaseJavaModule implements TurboModule { + public static final String NAME = "NavModule"; + + public NativeNavModuleSpec(ReactApplicationContext reactContext) { + super(reactContext); + } + + @Override + public @Nonnull String getName() { + return NAME; + } + + protected final void emitOnNavigationReady() { + mEventEmitterCallback.invoke("onNavigationReady"); + } + + protected final void emitOnLocationChanged(ReadableMap value) { + mEventEmitterCallback.invoke("onLocationChanged", value); + } + + protected final void emitOnArrival(ReadableMap value) { + mEventEmitterCallback.invoke("onArrival", value); + } + + protected final void emitOnRemainingTimeOrDistanceChanged() { + mEventEmitterCallback.invoke("onRemainingTimeOrDistanceChanged"); + } + + protected final void emitOnRouteChanged() { + mEventEmitterCallback.invoke("onRouteChanged"); + } + + protected final void emitOnReroutingRequestedByOffRoute() { + mEventEmitterCallback.invoke("onReroutingRequestedByOffRoute"); + } + + protected final void emitOnStartGuidance() { + mEventEmitterCallback.invoke("onStartGuidance"); + } + + protected final void emitOnTurnByTurn(ReadableMap value) { + mEventEmitterCallback.invoke("onTurnByTurn", value); + } + + protected final void emitOnRawLocationChanged(ReadableMap value) { + mEventEmitterCallback.invoke("onRawLocationChanged", value); + } + + protected final void emitOnTrafficUpdated() { + mEventEmitterCallback.invoke("onTrafficUpdated"); + } + + protected final void emitLogDebugInfo(ReadableMap value) { + mEventEmitterCallback.invoke("logDebugInfo", value); + } + + @ReactMethod + @DoNotStrip + public abstract void initializeNavigator(ReadableMap termsAndConditionsDialogOptions, double taskRemovedBehavior, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void cleanup(Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void setDestinations(ReadableArray waypoints, @Nullable ReadableMap routingOptions, @Nullable ReadableMap displayOptions, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void continueToNextDestination(Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void clearDestinations(Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void startGuidance(Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void stopGuidance(Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void setSpeedAlertOptions(@Nullable ReadableMap alertOptions, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void setAbnormalTerminatingReportingEnabled(boolean enabled); + + @ReactMethod + @DoNotStrip + public abstract void setAudioGuidanceType(double index, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void setBackgroundLocationUpdatesEnabled(boolean isEnabled); + + @ReactMethod + @DoNotStrip + public abstract void setTurnByTurnLoggingEnabled(boolean isEnabled); + + @ReactMethod + @DoNotStrip + public abstract void areTermsAccepted(Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void getCurrentRouteSegment(Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void getRouteSegments(Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void getCurrentTimeAndDistance(Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void getTraveledPath(Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void getNavSDKVersion(Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void stopUpdatingLocation(Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void startUpdatingLocation(Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void simulateLocation(ReadableMap location, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void resumeLocationSimulation(Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void pauseLocationSimulation(Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void simulateLocationsAlongExistingRoute(ReadableMap options, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void stopLocationSimulation(Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void resetTermsAccepted(); +} diff --git a/android/generated/java/com/google/maps/android/rn/navsdk/NativeNavViewModuleSpec.java b/android/generated/java/com/google/maps/android/rn/navsdk/NativeNavViewModuleSpec.java new file mode 100644 index 00000000..e47d64ff --- /dev/null +++ b/android/generated/java/com/google/maps/android/rn/navsdk/NativeNavViewModuleSpec.java @@ -0,0 +1,123 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateModuleJavaSpec.js + * + * @nolint + */ + +package com.google.maps.android.rn.navsdk; + +import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.turbomodule.core.interfaces.TurboModule; +import javax.annotation.Nonnull; + +public abstract class NativeNavViewModuleSpec extends ReactContextBaseJavaModule implements TurboModule { + public static final String NAME = "NavViewModule"; + + public NativeNavViewModuleSpec(ReactApplicationContext reactContext) { + super(reactContext); + } + + @Override + public @Nonnull String getName() { + return NAME; + } + + @ReactMethod + @DoNotStrip + public abstract void addCircle(double viewId, ReadableMap options, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void addMarker(double viewId, ReadableMap options, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void addPolyline(double viewId, ReadableMap options, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void addPolygon(double viewId, ReadableMap options, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void addGroundOverlay(double viewId, ReadableMap options, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void moveCamera(double viewId, ReadableMap cameraPosition, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void getCameraPosition(double viewId, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void getMyLocation(double viewId, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void getUiSettings(double viewId, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void isMyLocationEnabled(double viewId, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void showRouteOverview(double viewId, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void clearMapView(double viewId, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void removeMarker(double viewId, String id, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void removePolyline(double viewId, String id, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void removePolygon(double viewId, String id, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void removeCircle(double viewId, String id, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void removeGroundOverlay(double viewId, String id, Promise promise); + + @ReactMethod + @DoNotStrip + public abstract void setZoomLevel(double viewId, double level, Promise promise); +} diff --git a/android/generated/jni/CMakeLists.txt b/android/generated/jni/CMakeLists.txt new file mode 100644 index 00000000..b044479a --- /dev/null +++ b/android/generated/jni/CMakeLists.txt @@ -0,0 +1,36 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +cmake_minimum_required(VERSION 3.13) +set(CMAKE_VERBOSE_MAKEFILE on) + +file(GLOB react_codegen_SRCS CONFIGURE_DEPENDS *.cpp react/renderer/components/RNNavigationSdkSpec/*.cpp) + +add_library( + react_codegen_RNNavigationSdkSpec + OBJECT + ${react_codegen_SRCS} +) + +target_include_directories(react_codegen_RNNavigationSdkSpec PUBLIC . react/renderer/components/RNNavigationSdkSpec) + +target_link_libraries( + react_codegen_RNNavigationSdkSpec + fbjni + jsi + # We need to link different libraries based on whether we are building rncore or not, that's necessary + # because we want to break a circular dependency between react_codegen_rncore and reactnative + reactnative +) + +target_compile_options( + react_codegen_RNNavigationSdkSpec + PRIVATE + -DLOG_TAG=\"ReactNative\" + -fexceptions + -frtti + -std=c++20 + -Wall +) diff --git a/android/generated/jni/RNNavigationSdkSpec-generated.cpp b/android/generated/jni/RNNavigationSdkSpec-generated.cpp new file mode 100644 index 00000000..c314759b --- /dev/null +++ b/android/generated/jni/RNNavigationSdkSpec-generated.cpp @@ -0,0 +1,487 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateModuleJniCpp.js + */ + +#include "RNNavigationSdkSpec.h" + +namespace facebook::react { + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_isAutoScreenAvailable(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "isAutoScreenAvailable", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_setMapType(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, VoidKind, "setMapType", "(D)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_setMapStyle(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, VoidKind, "setMapStyle", "(Ljava/lang/String;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_clearMapView(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "clearMapView", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_addCircle(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "addCircle", "(Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_addMarker(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "addMarker", "(Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_addPolyline(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "addPolyline", "(Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_addPolygon(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "addPolygon", "(Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_addGroundOverlay(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "addGroundOverlay", "(Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_moveCamera(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "moveCamera", "(Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_removeMarker(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "removeMarker", "(Ljava/lang/String;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_removePolyline(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "removePolyline", "(Ljava/lang/String;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_removePolygon(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "removePolygon", "(Ljava/lang/String;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_removeCircle(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "removeCircle", "(Ljava/lang/String;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_removeGroundOverlay(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "removeGroundOverlay", "(Ljava/lang/String;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_setIndoorEnabled(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, VoidKind, "setIndoorEnabled", "(Z)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_setTrafficEnabled(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, VoidKind, "setTrafficEnabled", "(Z)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_setCompassEnabled(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, VoidKind, "setCompassEnabled", "(Z)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_setMyLocationEnabled(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, VoidKind, "setMyLocationEnabled", "(Z)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_setBuildingsEnabled(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, VoidKind, "setBuildingsEnabled", "(Z)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_setZoomLevel(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "setZoomLevel", "(DLcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_setMapPadding(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, VoidKind, "setMapPadding", "(DDDD)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_getCameraPosition(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "getCameraPosition", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_getMyLocation(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "getMyLocation", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_getUiSettings(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "getUiSettings", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavAutoModuleSpecJSI_isMyLocationEnabled(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "isMyLocationEnabled", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +NativeNavAutoModuleSpecJSI::NativeNavAutoModuleSpecJSI(const JavaTurboModule::InitParams ¶ms) + : JavaTurboModule(params) { + methodMap_["isAutoScreenAvailable"] = MethodMetadata {0, __hostFunction_NativeNavAutoModuleSpecJSI_isAutoScreenAvailable}; + methodMap_["setMapType"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleSpecJSI_setMapType}; + methodMap_["setMapStyle"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleSpecJSI_setMapStyle}; + methodMap_["clearMapView"] = MethodMetadata {0, __hostFunction_NativeNavAutoModuleSpecJSI_clearMapView}; + methodMap_["addCircle"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleSpecJSI_addCircle}; + methodMap_["addMarker"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleSpecJSI_addMarker}; + methodMap_["addPolyline"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleSpecJSI_addPolyline}; + methodMap_["addPolygon"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleSpecJSI_addPolygon}; + methodMap_["addGroundOverlay"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleSpecJSI_addGroundOverlay}; + methodMap_["moveCamera"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleSpecJSI_moveCamera}; + methodMap_["removeMarker"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleSpecJSI_removeMarker}; + methodMap_["removePolyline"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleSpecJSI_removePolyline}; + methodMap_["removePolygon"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleSpecJSI_removePolygon}; + methodMap_["removeCircle"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleSpecJSI_removeCircle}; + methodMap_["removeGroundOverlay"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleSpecJSI_removeGroundOverlay}; + methodMap_["setIndoorEnabled"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleSpecJSI_setIndoorEnabled}; + methodMap_["setTrafficEnabled"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleSpecJSI_setTrafficEnabled}; + methodMap_["setCompassEnabled"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleSpecJSI_setCompassEnabled}; + methodMap_["setMyLocationEnabled"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleSpecJSI_setMyLocationEnabled}; + methodMap_["setBuildingsEnabled"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleSpecJSI_setBuildingsEnabled}; + methodMap_["setZoomLevel"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleSpecJSI_setZoomLevel}; + methodMap_["setMapPadding"] = MethodMetadata {4, __hostFunction_NativeNavAutoModuleSpecJSI_setMapPadding}; + methodMap_["getCameraPosition"] = MethodMetadata {0, __hostFunction_NativeNavAutoModuleSpecJSI_getCameraPosition}; + methodMap_["getMyLocation"] = MethodMetadata {0, __hostFunction_NativeNavAutoModuleSpecJSI_getMyLocation}; + methodMap_["getUiSettings"] = MethodMetadata {0, __hostFunction_NativeNavAutoModuleSpecJSI_getUiSettings}; + methodMap_["isMyLocationEnabled"] = MethodMetadata {0, __hostFunction_NativeNavAutoModuleSpecJSI_isMyLocationEnabled}; + eventEmitterMap_["onAutoScreenAvailabilityChanged"] = std::make_shared>(); + eventEmitterMap_["onCustomNavigationAutoEvent"] = std::make_shared>(); + setEventEmitterCallback(params.instance); +} +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_initializeNavigator(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "initializeNavigator", "(Lcom/facebook/react/bridge/ReadableMap;DLcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_cleanup(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "cleanup", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_setDestinations(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "setDestinations", "(Lcom/facebook/react/bridge/ReadableArray;Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_continueToNextDestination(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "continueToNextDestination", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_clearDestinations(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "clearDestinations", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_startGuidance(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "startGuidance", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_stopGuidance(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "stopGuidance", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_setSpeedAlertOptions(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "setSpeedAlertOptions", "(Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_setAbnormalTerminatingReportingEnabled(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, VoidKind, "setAbnormalTerminatingReportingEnabled", "(Z)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_setAudioGuidanceType(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "setAudioGuidanceType", "(DLcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_setBackgroundLocationUpdatesEnabled(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, VoidKind, "setBackgroundLocationUpdatesEnabled", "(Z)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_setTurnByTurnLoggingEnabled(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, VoidKind, "setTurnByTurnLoggingEnabled", "(Z)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_areTermsAccepted(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "areTermsAccepted", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_getCurrentRouteSegment(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "getCurrentRouteSegment", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_getRouteSegments(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "getRouteSegments", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_getCurrentTimeAndDistance(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "getCurrentTimeAndDistance", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_getTraveledPath(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "getTraveledPath", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_getNavSDKVersion(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "getNavSDKVersion", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_stopUpdatingLocation(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "stopUpdatingLocation", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_startUpdatingLocation(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "startUpdatingLocation", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_simulateLocation(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "simulateLocation", "(Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_resumeLocationSimulation(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "resumeLocationSimulation", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_pauseLocationSimulation(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "pauseLocationSimulation", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_simulateLocationsAlongExistingRoute(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "simulateLocationsAlongExistingRoute", "(Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_stopLocationSimulation(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "stopLocationSimulation", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavModuleSpecJSI_resetTermsAccepted(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, VoidKind, "resetTermsAccepted", "()V", args, count, cachedMethodId); +} + +NativeNavModuleSpecJSI::NativeNavModuleSpecJSI(const JavaTurboModule::InitParams ¶ms) + : JavaTurboModule(params) { + methodMap_["initializeNavigator"] = MethodMetadata {2, __hostFunction_NativeNavModuleSpecJSI_initializeNavigator}; + methodMap_["cleanup"] = MethodMetadata {0, __hostFunction_NativeNavModuleSpecJSI_cleanup}; + methodMap_["setDestinations"] = MethodMetadata {3, __hostFunction_NativeNavModuleSpecJSI_setDestinations}; + methodMap_["continueToNextDestination"] = MethodMetadata {0, __hostFunction_NativeNavModuleSpecJSI_continueToNextDestination}; + methodMap_["clearDestinations"] = MethodMetadata {0, __hostFunction_NativeNavModuleSpecJSI_clearDestinations}; + methodMap_["startGuidance"] = MethodMetadata {0, __hostFunction_NativeNavModuleSpecJSI_startGuidance}; + methodMap_["stopGuidance"] = MethodMetadata {0, __hostFunction_NativeNavModuleSpecJSI_stopGuidance}; + methodMap_["setSpeedAlertOptions"] = MethodMetadata {1, __hostFunction_NativeNavModuleSpecJSI_setSpeedAlertOptions}; + methodMap_["setAbnormalTerminatingReportingEnabled"] = MethodMetadata {1, __hostFunction_NativeNavModuleSpecJSI_setAbnormalTerminatingReportingEnabled}; + methodMap_["setAudioGuidanceType"] = MethodMetadata {1, __hostFunction_NativeNavModuleSpecJSI_setAudioGuidanceType}; + methodMap_["setBackgroundLocationUpdatesEnabled"] = MethodMetadata {1, __hostFunction_NativeNavModuleSpecJSI_setBackgroundLocationUpdatesEnabled}; + methodMap_["setTurnByTurnLoggingEnabled"] = MethodMetadata {1, __hostFunction_NativeNavModuleSpecJSI_setTurnByTurnLoggingEnabled}; + methodMap_["areTermsAccepted"] = MethodMetadata {0, __hostFunction_NativeNavModuleSpecJSI_areTermsAccepted}; + methodMap_["getCurrentRouteSegment"] = MethodMetadata {0, __hostFunction_NativeNavModuleSpecJSI_getCurrentRouteSegment}; + methodMap_["getRouteSegments"] = MethodMetadata {0, __hostFunction_NativeNavModuleSpecJSI_getRouteSegments}; + methodMap_["getCurrentTimeAndDistance"] = MethodMetadata {0, __hostFunction_NativeNavModuleSpecJSI_getCurrentTimeAndDistance}; + methodMap_["getTraveledPath"] = MethodMetadata {0, __hostFunction_NativeNavModuleSpecJSI_getTraveledPath}; + methodMap_["getNavSDKVersion"] = MethodMetadata {0, __hostFunction_NativeNavModuleSpecJSI_getNavSDKVersion}; + methodMap_["stopUpdatingLocation"] = MethodMetadata {0, __hostFunction_NativeNavModuleSpecJSI_stopUpdatingLocation}; + methodMap_["startUpdatingLocation"] = MethodMetadata {0, __hostFunction_NativeNavModuleSpecJSI_startUpdatingLocation}; + methodMap_["simulateLocation"] = MethodMetadata {1, __hostFunction_NativeNavModuleSpecJSI_simulateLocation}; + methodMap_["resumeLocationSimulation"] = MethodMetadata {0, __hostFunction_NativeNavModuleSpecJSI_resumeLocationSimulation}; + methodMap_["pauseLocationSimulation"] = MethodMetadata {0, __hostFunction_NativeNavModuleSpecJSI_pauseLocationSimulation}; + methodMap_["simulateLocationsAlongExistingRoute"] = MethodMetadata {1, __hostFunction_NativeNavModuleSpecJSI_simulateLocationsAlongExistingRoute}; + methodMap_["stopLocationSimulation"] = MethodMetadata {0, __hostFunction_NativeNavModuleSpecJSI_stopLocationSimulation}; + methodMap_["resetTermsAccepted"] = MethodMetadata {0, __hostFunction_NativeNavModuleSpecJSI_resetTermsAccepted}; + eventEmitterMap_["onNavigationReady"] = std::make_shared>(); + eventEmitterMap_["onLocationChanged"] = std::make_shared>(); + eventEmitterMap_["onArrival"] = std::make_shared>(); + eventEmitterMap_["onRemainingTimeOrDistanceChanged"] = std::make_shared>(); + eventEmitterMap_["onRouteChanged"] = std::make_shared>(); + eventEmitterMap_["onReroutingRequestedByOffRoute"] = std::make_shared>(); + eventEmitterMap_["onStartGuidance"] = std::make_shared>(); + eventEmitterMap_["onTurnByTurn"] = std::make_shared>(); + eventEmitterMap_["onRawLocationChanged"] = std::make_shared>(); + eventEmitterMap_["onTrafficUpdated"] = std::make_shared>(); + eventEmitterMap_["logDebugInfo"] = std::make_shared>(); + setEventEmitterCallback(params.instance); +} +static facebook::jsi::Value __hostFunction_NativeNavViewModuleSpecJSI_addCircle(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "addCircle", "(DLcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavViewModuleSpecJSI_addMarker(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "addMarker", "(DLcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavViewModuleSpecJSI_addPolyline(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "addPolyline", "(DLcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavViewModuleSpecJSI_addPolygon(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "addPolygon", "(DLcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavViewModuleSpecJSI_addGroundOverlay(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "addGroundOverlay", "(DLcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavViewModuleSpecJSI_moveCamera(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "moveCamera", "(DLcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavViewModuleSpecJSI_getCameraPosition(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "getCameraPosition", "(DLcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavViewModuleSpecJSI_getMyLocation(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "getMyLocation", "(DLcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavViewModuleSpecJSI_getUiSettings(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "getUiSettings", "(DLcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavViewModuleSpecJSI_isMyLocationEnabled(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "isMyLocationEnabled", "(DLcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavViewModuleSpecJSI_showRouteOverview(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "showRouteOverview", "(DLcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavViewModuleSpecJSI_clearMapView(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "clearMapView", "(DLcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavViewModuleSpecJSI_removeMarker(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "removeMarker", "(DLjava/lang/String;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavViewModuleSpecJSI_removePolyline(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "removePolyline", "(DLjava/lang/String;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavViewModuleSpecJSI_removePolygon(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "removePolygon", "(DLjava/lang/String;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavViewModuleSpecJSI_removeCircle(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "removeCircle", "(DLjava/lang/String;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavViewModuleSpecJSI_removeGroundOverlay(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "removeGroundOverlay", "(DLjava/lang/String;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +static facebook::jsi::Value __hostFunction_NativeNavViewModuleSpecJSI_setZoomLevel(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, PromiseKind, "setZoomLevel", "(DDLcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId); +} + +NativeNavViewModuleSpecJSI::NativeNavViewModuleSpecJSI(const JavaTurboModule::InitParams ¶ms) + : JavaTurboModule(params) { + methodMap_["addCircle"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleSpecJSI_addCircle}; + methodMap_["addMarker"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleSpecJSI_addMarker}; + methodMap_["addPolyline"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleSpecJSI_addPolyline}; + methodMap_["addPolygon"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleSpecJSI_addPolygon}; + methodMap_["addGroundOverlay"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleSpecJSI_addGroundOverlay}; + methodMap_["moveCamera"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleSpecJSI_moveCamera}; + methodMap_["getCameraPosition"] = MethodMetadata {1, __hostFunction_NativeNavViewModuleSpecJSI_getCameraPosition}; + methodMap_["getMyLocation"] = MethodMetadata {1, __hostFunction_NativeNavViewModuleSpecJSI_getMyLocation}; + methodMap_["getUiSettings"] = MethodMetadata {1, __hostFunction_NativeNavViewModuleSpecJSI_getUiSettings}; + methodMap_["isMyLocationEnabled"] = MethodMetadata {1, __hostFunction_NativeNavViewModuleSpecJSI_isMyLocationEnabled}; + methodMap_["showRouteOverview"] = MethodMetadata {1, __hostFunction_NativeNavViewModuleSpecJSI_showRouteOverview}; + methodMap_["clearMapView"] = MethodMetadata {1, __hostFunction_NativeNavViewModuleSpecJSI_clearMapView}; + methodMap_["removeMarker"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleSpecJSI_removeMarker}; + methodMap_["removePolyline"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleSpecJSI_removePolyline}; + methodMap_["removePolygon"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleSpecJSI_removePolygon}; + methodMap_["removeCircle"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleSpecJSI_removeCircle}; + methodMap_["removeGroundOverlay"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleSpecJSI_removeGroundOverlay}; + methodMap_["setZoomLevel"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleSpecJSI_setZoomLevel}; +} + +std::shared_ptr RNNavigationSdkSpec_ModuleProvider(const std::string &moduleName, const JavaTurboModule::InitParams ¶ms) { + if (moduleName == "NavAutoModule") { + return std::make_shared(params); + } + if (moduleName == "NavModule") { + return std::make_shared(params); + } + if (moduleName == "NavViewModule") { + return std::make_shared(params); + } + return nullptr; +} + +} // namespace facebook::react diff --git a/android/generated/jni/RNNavigationSdkSpec.h b/android/generated/jni/RNNavigationSdkSpec.h new file mode 100644 index 00000000..ecfa5b1d --- /dev/null +++ b/android/generated/jni/RNNavigationSdkSpec.h @@ -0,0 +1,63 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateModuleJniH.js + */ + +#pragma once + +#include +#include +#include + +namespace facebook::react { + +/** + * JNI C++ class for module 'NativeNavAutoModule' + */ +class JSI_EXPORT NativeNavAutoModuleSpecJSI : public JavaTurboModule { +public: + NativeNavAutoModuleSpecJSI(const JavaTurboModule::InitParams ¶ms); +}; + +/** + * JNI C++ class for module 'NativeNavModule' + */ +class JSI_EXPORT NativeNavModuleSpecJSI : public JavaTurboModule { +public: + NativeNavModuleSpecJSI(const JavaTurboModule::InitParams ¶ms); +}; + +/** + * JNI C++ class for module 'NativeNavViewModule' + */ +class JSI_EXPORT NativeNavViewModuleSpecJSI : public JavaTurboModule { +public: + NativeNavViewModuleSpecJSI(const JavaTurboModule::InitParams ¶ms); +}; + + +JSI_EXPORT +std::shared_ptr RNNavigationSdkSpec_ModuleProvider(const std::string &moduleName, const JavaTurboModule::InitParams ¶ms); + +} // namespace facebook::react diff --git a/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/ComponentDescriptors.cpp b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/ComponentDescriptors.cpp new file mode 100644 index 00000000..85f87836 --- /dev/null +++ b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/ComponentDescriptors.cpp @@ -0,0 +1,36 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateComponentDescriptorCpp.js + */ + +#include "ComponentDescriptors.h" +#include +#include + +namespace facebook::react { + +void RNNavigationSdkSpec_registerComponentDescriptorsFromCodegen( + std::shared_ptr registry) { +registry->add(concreteComponentDescriptorProvider()); +} + +} // namespace facebook::react diff --git a/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/ComponentDescriptors.h b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/ComponentDescriptors.h new file mode 100644 index 00000000..5d39c69b --- /dev/null +++ b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/ComponentDescriptors.h @@ -0,0 +1,40 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateComponentDescriptorH.js + */ + +#pragma once + +#include "ShadowNodes.h" +#include +#include + +namespace facebook::react { + +using NavViewComponentDescriptor = ConcreteComponentDescriptor; + +void RNNavigationSdkSpec_registerComponentDescriptorsFromCodegen( + std::shared_ptr registry); + +} // namespace facebook::react diff --git a/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/EventEmitters.cpp b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/EventEmitters.cpp new file mode 100644 index 00000000..055eb82a --- /dev/null +++ b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/EventEmitters.cpp @@ -0,0 +1,201 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateEventEmitterCpp.js + */ + +#include "EventEmitters.h" + + +namespace facebook::react { + +void NavViewEventEmitter::onMapReady(OnMapReady $event) const { + dispatchEvent("mapReady", [](jsi::Runtime &runtime) { + auto $payload = jsi::Object(runtime); + + return $payload; + }); +} + + +void NavViewEventEmitter::onMapClick(OnMapClick $event) const { + dispatchEvent("mapClick", [$event=std::move($event)](jsi::Runtime &runtime) { + auto $payload = jsi::Object(runtime); + $payload.setProperty(runtime, "lat", $event.lat); +$payload.setProperty(runtime, "lng", $event.lng); + return $payload; + }); +} + + +void NavViewEventEmitter::onMarkerClick(OnMarkerClick $event) const { + dispatchEvent("markerClick", [$event=std::move($event)](jsi::Runtime &runtime) { + auto $payload = jsi::Object(runtime); + { + auto position = jsi::Object(runtime); + position.setProperty(runtime, "lat", $event.position.lat); + position.setProperty(runtime, "lng", $event.position.lng); + $payload.setProperty(runtime, "position", position); +} +$payload.setProperty(runtime, "id", $event.id); +$payload.setProperty(runtime, "title", $event.title); +$payload.setProperty(runtime, "alpha", $event.alpha); +$payload.setProperty(runtime, "rotation", $event.rotation); +$payload.setProperty(runtime, "snippet", $event.snippet); +$payload.setProperty(runtime, "zIndex", $event.zIndex); + return $payload; + }); +} + + +void NavViewEventEmitter::onPolylineClick(OnPolylineClick $event) const { + dispatchEvent("polylineClick", [$event=std::move($event)](jsi::Runtime &runtime) { + auto $payload = jsi::Object(runtime); + + auto points = jsi::Array(runtime, $event.points.size()); + size_t pointsIndex = 0; + for (auto pointsValue : $event.points) { + auto pointsObject = jsi::Object(runtime); + pointsObject.setProperty(runtime, "lat", pointsValue.lat); +pointsObject.setProperty(runtime, "lng", pointsValue.lng); + points.setValueAtIndex(runtime, pointsIndex++, pointsObject); + } + $payload.setProperty(runtime, "points", points); + +$payload.setProperty(runtime, "id", $event.id); +$payload.setProperty(runtime, "color", $event.color); +$payload.setProperty(runtime, "width", $event.width); +$payload.setProperty(runtime, "jointType", $event.jointType); +$payload.setProperty(runtime, "zIndex", $event.zIndex); + return $payload; + }); +} + + +void NavViewEventEmitter::onPolygonClick(OnPolygonClick $event) const { + dispatchEvent("polygonClick", [$event=std::move($event)](jsi::Runtime &runtime) { + auto $payload = jsi::Object(runtime); + + auto points = jsi::Array(runtime, $event.points.size()); + size_t pointsIndex = 0; + for (auto pointsValue : $event.points) { + auto pointsObject = jsi::Object(runtime); + pointsObject.setProperty(runtime, "lat", pointsValue.lat); +pointsObject.setProperty(runtime, "lng", pointsValue.lng); + points.setValueAtIndex(runtime, pointsIndex++, pointsObject); + } + $payload.setProperty(runtime, "points", points); + + + auto holes = jsi::Array(runtime, $event.holes.size()); + size_t holesIndex = 0; + for (auto holesValue : $event.holes) { + auto holesArray = jsi::Array(runtime, holesValue.size()); + size_t holesIndexInternal = 0; + for (auto holesValueInternal : holesValue) { + auto holesArrayObject = jsi::Object(runtime); + holesArrayObject.setProperty(runtime, "lat", holesValueInternal.lat); +holesArrayObject.setProperty(runtime, "lng", holesValueInternal.lng); + holesArray.setValueAtIndex(runtime, holesIndexInternal++, holesArrayObject); + } + holes.setValueAtIndex(runtime, holesIndex++, holesArray); + } + $payload.setProperty(runtime, "holes", holes); + +$payload.setProperty(runtime, "id", $event.id); +$payload.setProperty(runtime, "fillColor", $event.fillColor); +$payload.setProperty(runtime, "strokeWidth", $event.strokeWidth); +$payload.setProperty(runtime, "strokeColor", $event.strokeColor); +$payload.setProperty(runtime, "strokeJointType", $event.strokeJointType); +$payload.setProperty(runtime, "zIndex", $event.zIndex); +$payload.setProperty(runtime, "geodesic", $event.geodesic); + return $payload; + }); +} + + +void NavViewEventEmitter::onCircleClick(OnCircleClick $event) const { + dispatchEvent("circleClick", [$event=std::move($event)](jsi::Runtime &runtime) { + auto $payload = jsi::Object(runtime); + { + auto center = jsi::Object(runtime); + center.setProperty(runtime, "lat", $event.center.lat); + center.setProperty(runtime, "lng", $event.center.lng); + $payload.setProperty(runtime, "center", center); +} +$payload.setProperty(runtime, "id", $event.id); +$payload.setProperty(runtime, "fillColor", $event.fillColor); +$payload.setProperty(runtime, "strokeWidth", $event.strokeWidth); +$payload.setProperty(runtime, "strokeColor", $event.strokeColor); +$payload.setProperty(runtime, "radius", $event.radius); +$payload.setProperty(runtime, "zIndex", $event.zIndex); + return $payload; + }); +} + + +void NavViewEventEmitter::onGroundOverlayClick(OnGroundOverlayClick $event) const { + dispatchEvent("groundOverlayClick", [$event=std::move($event)](jsi::Runtime &runtime) { + auto $payload = jsi::Object(runtime); + $payload.setProperty(runtime, "id", $event.id); + return $payload; + }); +} + + +void NavViewEventEmitter::onMarkerInfoWindowTapped(OnMarkerInfoWindowTapped $event) const { + dispatchEvent("markerInfoWindowTapped", [$event=std::move($event)](jsi::Runtime &runtime) { + auto $payload = jsi::Object(runtime); + { + auto position = jsi::Object(runtime); + position.setProperty(runtime, "lat", $event.position.lat); + position.setProperty(runtime, "lng", $event.position.lng); + $payload.setProperty(runtime, "position", position); +} +$payload.setProperty(runtime, "id", $event.id); +$payload.setProperty(runtime, "title", $event.title); +$payload.setProperty(runtime, "alpha", $event.alpha); +$payload.setProperty(runtime, "rotation", $event.rotation); +$payload.setProperty(runtime, "snippet", $event.snippet); +$payload.setProperty(runtime, "zIndex", $event.zIndex); + return $payload; + }); +} + + +void NavViewEventEmitter::onRecenterButtonClick(OnRecenterButtonClick $event) const { + dispatchEvent("recenterButtonClick", [](jsi::Runtime &runtime) { + auto $payload = jsi::Object(runtime); + + return $payload; + }); +} + + +void NavViewEventEmitter::onPromptVisibilityChanged(OnPromptVisibilityChanged $event) const { + dispatchEvent("promptVisibilityChanged", [$event=std::move($event)](jsi::Runtime &runtime) { + auto $payload = jsi::Object(runtime); + $payload.setProperty(runtime, "visible", $event.visible); + return $payload; + }); +} + +} // namespace facebook::react diff --git a/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/EventEmitters.h b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/EventEmitters.h new file mode 100644 index 00000000..d37a2726 --- /dev/null +++ b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/EventEmitters.h @@ -0,0 +1,157 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateEventEmitterH.js + */ +#pragma once + +#include + + +namespace facebook::react { +class NavViewEventEmitter : public ViewEventEmitter { + public: + using ViewEventEmitter::ViewEventEmitter; + + struct OnMapReady { + + }; + + struct OnMapClick { + Float lat; + Float lng; + }; + + struct OnMarkerClickPosition { + Float lat; + Float lng; + }; + + struct OnMarkerClick { + OnMarkerClickPosition position; + std::string id; + std::string title; + Float alpha; + Float rotation; + std::string snippet; + int zIndex; + }; + + struct OnPolylineClickPoints { + Float lat; + Float lng; + }; + + struct OnPolylineClick { + std::vector points; + std::string id; + std::string color; + Float width; + int jointType; + int zIndex; + }; + + struct OnPolygonClickPoints { + Float lat; + Float lng; + }; + + struct OnPolygonClickHoles { + Float lat; + Float lng; + }; + + struct OnPolygonClick { + std::vector points; + std::vector> holes; + std::string id; + std::string fillColor; + Float strokeWidth; + std::string strokeColor; + int strokeJointType; + int zIndex; + bool geodesic; + }; + + struct OnCircleClickCenter { + Float lat; + Float lng; + }; + + struct OnCircleClick { + OnCircleClickCenter center; + std::string id; + std::string fillColor; + Float strokeWidth; + std::string strokeColor; + Float radius; + int zIndex; + }; + + struct OnGroundOverlayClick { + std::string id; + }; + + struct OnMarkerInfoWindowTappedPosition { + Float lat; + Float lng; + }; + + struct OnMarkerInfoWindowTapped { + OnMarkerInfoWindowTappedPosition position; + std::string id; + std::string title; + Float alpha; + Float rotation; + std::string snippet; + int zIndex; + }; + + struct OnRecenterButtonClick { + + }; + + struct OnPromptVisibilityChanged { + bool visible; + }; + void onMapReady(OnMapReady value) const; + + void onMapClick(OnMapClick value) const; + + void onMarkerClick(OnMarkerClick value) const; + + void onPolylineClick(OnPolylineClick value) const; + + void onPolygonClick(OnPolygonClick value) const; + + void onCircleClick(OnCircleClick value) const; + + void onGroundOverlayClick(OnGroundOverlayClick value) const; + + void onMarkerInfoWindowTapped(OnMarkerInfoWindowTapped value) const; + + void onRecenterButtonClick(OnRecenterButtonClick value) const; + + void onPromptVisibilityChanged(OnPromptVisibilityChanged value) const; +}; +} // namespace facebook::react diff --git a/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/Props.cpp b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/Props.cpp new file mode 100644 index 00000000..2f8746a1 --- /dev/null +++ b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/Props.cpp @@ -0,0 +1,73 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GeneratePropsCpp.js + */ + +#include "Props.h" +#include +#include +#include + +namespace facebook::react { + +NavViewProps::NavViewProps( + const PropsParserContext &context, + const NavViewProps &sourceProps, + const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), + + viewType(convertRawProp(context, rawProps, "viewType", sourceProps.viewType, {0})), + nativeID(convertRawProp(context, rawProps, "nativeID", sourceProps.nativeID, {})), + mapId(convertRawProp(context, rawProps, "mapId", sourceProps.mapId, {})), + mapType(convertRawProp(context, rawProps, "mapType", sourceProps.mapType, {1})), + mapPadding(convertRawProp(context, rawProps, "mapPadding", sourceProps.mapPadding, {})), + navigationUIEnabled(convertRawProp(context, rawProps, "navigationUIEnabled", sourceProps.navigationUIEnabled, {})), + tripProgressBarEnabled(convertRawProp(context, rawProps, "tripProgressBarEnabled", sourceProps.tripProgressBarEnabled, {false})), + trafficIncidentsCardEnabled(convertRawProp(context, rawProps, "trafficIncidentsCardEnabled", sourceProps.trafficIncidentsCardEnabled, {true})), + headerEnabled(convertRawProp(context, rawProps, "headerEnabled", sourceProps.headerEnabled, {true})), + footerEnabled(convertRawProp(context, rawProps, "footerEnabled", sourceProps.footerEnabled, {true})), + speedometerEnabled(convertRawProp(context, rawProps, "speedometerEnabled", sourceProps.speedometerEnabled, {true})), + speedLimitIconEnabled(convertRawProp(context, rawProps, "speedLimitIconEnabled", sourceProps.speedLimitIconEnabled, {true})), + recenterButtonEnabled(convertRawProp(context, rawProps, "recenterButtonEnabled", sourceProps.recenterButtonEnabled, {true})), + navigationViewStylingOptions(convertRawProp(context, rawProps, "navigationViewStylingOptions", sourceProps.navigationViewStylingOptions, {})), + nightMode(convertRawProp(context, rawProps, "nightMode", sourceProps.nightMode, {0})), + followingPerspective(convertRawProp(context, rawProps, "followingPerspective", sourceProps.followingPerspective, {0})), + mapStyle(convertRawProp(context, rawProps, "mapStyle", sourceProps.mapStyle, {})), + mapToolbarEnabled(convertRawProp(context, rawProps, "mapToolbarEnabled", sourceProps.mapToolbarEnabled, {true})), + indoorEnabled(convertRawProp(context, rawProps, "indoorEnabled", sourceProps.indoorEnabled, {true})), + trafficEnabled(convertRawProp(context, rawProps, "trafficEnabled", sourceProps.trafficEnabled, {false})), + compassEnabled(convertRawProp(context, rawProps, "compassEnabled", sourceProps.compassEnabled, {true})), + myLocationButtonEnabled(convertRawProp(context, rawProps, "myLocationButtonEnabled", sourceProps.myLocationButtonEnabled, {true})), + myLocationEnabled(convertRawProp(context, rawProps, "myLocationEnabled", sourceProps.myLocationEnabled, {false})), + rotateGesturesEnabled(convertRawProp(context, rawProps, "rotateGesturesEnabled", sourceProps.rotateGesturesEnabled, {true})), + scrollGesturesEnabled(convertRawProp(context, rawProps, "scrollGesturesEnabled", sourceProps.scrollGesturesEnabled, {true})), + scrollGesturesEnabledDuringRotateOrZoom(convertRawProp(context, rawProps, "scrollGesturesEnabledDuringRotateOrZoom", sourceProps.scrollGesturesEnabledDuringRotateOrZoom, {true})), + tiltGesturesEnabled(convertRawProp(context, rawProps, "tiltGesturesEnabled", sourceProps.tiltGesturesEnabled, {true})), + zoomControlsEnabled(convertRawProp(context, rawProps, "zoomControlsEnabled", sourceProps.zoomControlsEnabled, {true})), + zoomGesturesEnabled(convertRawProp(context, rawProps, "zoomGesturesEnabled", sourceProps.zoomGesturesEnabled, {true})), + buildingsEnabled(convertRawProp(context, rawProps, "buildingsEnabled", sourceProps.buildingsEnabled, {true})), + reportIncidentButtonEnabled(convertRawProp(context, rawProps, "reportIncidentButtonEnabled", sourceProps.reportIncidentButtonEnabled, {true})), + minZoomLevel(convertRawProp(context, rawProps, "minZoomLevel", sourceProps.minZoomLevel, {})), + maxZoomLevel(convertRawProp(context, rawProps, "maxZoomLevel", sourceProps.maxZoomLevel, {})), + initialCameraPosition(convertRawProp(context, rawProps, "initialCameraPosition", sourceProps.initialCameraPosition, {})) + {} + +} // namespace facebook::react diff --git a/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/Props.h b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/Props.h new file mode 100644 index 00000000..d860894d --- /dev/null +++ b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/Props.h @@ -0,0 +1,162 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GeneratePropsH.js + */ +#pragma once + +#include +#include +#include + +namespace facebook::react { + +struct NavViewMapPaddingStruct { + int top{0}; + int left{0}; + int bottom{0}; + int right{0}; +}; + +static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, NavViewMapPaddingStruct &result) { + auto map = (std::unordered_map)value; + + auto tmp_top = map.find("top"); + if (tmp_top != map.end()) { + fromRawValue(context, tmp_top->second, result.top); + } + auto tmp_left = map.find("left"); + if (tmp_left != map.end()) { + fromRawValue(context, tmp_left->second, result.left); + } + auto tmp_bottom = map.find("bottom"); + if (tmp_bottom != map.end()) { + fromRawValue(context, tmp_bottom->second, result.bottom); + } + auto tmp_right = map.find("right"); + if (tmp_right != map.end()) { + fromRawValue(context, tmp_right->second, result.right); + } +} + +static inline std::string toString(const NavViewMapPaddingStruct &value) { + return "[Object NavViewMapPaddingStruct]"; +} + +struct NavViewInitialCameraPositionTargetStruct { + Float lat{}; + Float lng{}; +}; + +static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, NavViewInitialCameraPositionTargetStruct &result) { + auto map = (std::unordered_map)value; + + auto tmp_lat = map.find("lat"); + if (tmp_lat != map.end()) { + fromRawValue(context, tmp_lat->second, result.lat); + } + auto tmp_lng = map.find("lng"); + if (tmp_lng != map.end()) { + fromRawValue(context, tmp_lng->second, result.lng); + } +} + +static inline std::string toString(const NavViewInitialCameraPositionTargetStruct &value) { + return "[Object NavViewInitialCameraPositionTargetStruct]"; +} + +struct NavViewInitialCameraPositionStruct { + NavViewInitialCameraPositionTargetStruct target{}; + Float bearing{}; + Float tilt{}; + Float zoom{}; +}; + +static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, NavViewInitialCameraPositionStruct &result) { + auto map = (std::unordered_map)value; + + auto tmp_target = map.find("target"); + if (tmp_target != map.end()) { + fromRawValue(context, tmp_target->second, result.target); + } + auto tmp_bearing = map.find("bearing"); + if (tmp_bearing != map.end()) { + fromRawValue(context, tmp_bearing->second, result.bearing); + } + auto tmp_tilt = map.find("tilt"); + if (tmp_tilt != map.end()) { + fromRawValue(context, tmp_tilt->second, result.tilt); + } + auto tmp_zoom = map.find("zoom"); + if (tmp_zoom != map.end()) { + fromRawValue(context, tmp_zoom->second, result.zoom); + } +} + +static inline std::string toString(const NavViewInitialCameraPositionStruct &value) { + return "[Object NavViewInitialCameraPositionStruct]"; +} +class NavViewProps final : public ViewProps { + public: + NavViewProps() = default; + NavViewProps(const PropsParserContext& context, const NavViewProps &sourceProps, const RawProps &rawProps); + +#pragma mark - Props + + int viewType{0}; + std::string nativeID{}; + std::string mapId{}; + int mapType{1}; + NavViewMapPaddingStruct mapPadding{}; + bool navigationUIEnabled{}; + bool tripProgressBarEnabled{false}; + bool trafficIncidentsCardEnabled{true}; + bool headerEnabled{true}; + bool footerEnabled{true}; + bool speedometerEnabled{true}; + bool speedLimitIconEnabled{true}; + bool recenterButtonEnabled{true}; + folly::dynamic navigationViewStylingOptions{}; + int nightMode{0}; + int followingPerspective{0}; + std::string mapStyle{}; + bool mapToolbarEnabled{true}; + bool indoorEnabled{true}; + bool trafficEnabled{false}; + bool compassEnabled{true}; + bool myLocationButtonEnabled{true}; + bool myLocationEnabled{false}; + bool rotateGesturesEnabled{true}; + bool scrollGesturesEnabled{true}; + bool scrollGesturesEnabledDuringRotateOrZoom{true}; + bool tiltGesturesEnabled{true}; + bool zoomControlsEnabled{true}; + bool zoomGesturesEnabled{true}; + bool buildingsEnabled{true}; + bool reportIncidentButtonEnabled{true}; + Float minZoomLevel{}; + Float maxZoomLevel{}; + NavViewInitialCameraPositionStruct initialCameraPosition{}; +}; + +} // namespace facebook::react diff --git a/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/RNNavigationSdkSpecJSI-generated.cpp b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/RNNavigationSdkSpecJSI-generated.cpp new file mode 100644 index 00000000..e55443dc --- /dev/null +++ b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/RNNavigationSdkSpecJSI-generated.cpp @@ -0,0 +1,539 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateModuleCpp.js + */ + +#include "RNNavigationSdkSpecJSI.h" + +namespace facebook::react { + +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_isAutoScreenAvailable(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->isAutoScreenAvailable( + rt + ); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_setMapType(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->setMapType( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber() + ); + return jsi::Value::undefined(); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_setMapStyle(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->setMapStyle( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asString(rt) + ); + return jsi::Value::undefined(); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_clearMapView(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->clearMapView( + rt + ); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_addCircle(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->addCircle( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asObject(rt) + ); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_addMarker(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->addMarker( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asObject(rt) + ); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_addPolyline(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->addPolyline( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asObject(rt) + ); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_addPolygon(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->addPolygon( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asObject(rt) + ); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_addGroundOverlay(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->addGroundOverlay( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asObject(rt) + ); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_moveCamera(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->moveCamera( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asObject(rt) + ); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_removeMarker(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->removeMarker( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asString(rt) + ); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_removePolyline(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->removePolyline( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asString(rt) + ); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_removePolygon(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->removePolygon( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asString(rt) + ); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_removeCircle(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->removeCircle( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asString(rt) + ); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_removeGroundOverlay(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->removeGroundOverlay( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asString(rt) + ); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_setIndoorEnabled(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->setIndoorEnabled( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asBool() + ); + return jsi::Value::undefined(); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_setTrafficEnabled(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->setTrafficEnabled( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asBool() + ); + return jsi::Value::undefined(); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_setCompassEnabled(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->setCompassEnabled( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asBool() + ); + return jsi::Value::undefined(); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_setMyLocationEnabled(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->setMyLocationEnabled( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asBool() + ); + return jsi::Value::undefined(); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_setBuildingsEnabled(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->setBuildingsEnabled( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asBool() + ); + return jsi::Value::undefined(); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_setZoomLevel(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->setZoomLevel( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber() + ); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_setMapPadding(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->setMapPadding( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber(), + count <= 1 ? throw jsi::JSError(rt, "Expected argument in position 1 to be passed") : args[1].asNumber(), + count <= 2 ? throw jsi::JSError(rt, "Expected argument in position 2 to be passed") : args[2].asNumber(), + count <= 3 ? throw jsi::JSError(rt, "Expected argument in position 3 to be passed") : args[3].asNumber() + ); + return jsi::Value::undefined(); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_getCameraPosition(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getCameraPosition( + rt + ); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_getMyLocation(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getMyLocation( + rt + ); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_getUiSettings(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getUiSettings( + rt + ); +} +static jsi::Value __hostFunction_NativeNavAutoModuleCxxSpecJSI_isMyLocationEnabled(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->isMyLocationEnabled( + rt + ); +} + +NativeNavAutoModuleCxxSpecJSI::NativeNavAutoModuleCxxSpecJSI(std::shared_ptr jsInvoker) + : TurboModule("NavAutoModule", jsInvoker) { + methodMap_["isAutoScreenAvailable"] = MethodMetadata {0, __hostFunction_NativeNavAutoModuleCxxSpecJSI_isAutoScreenAvailable}; + methodMap_["setMapType"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleCxxSpecJSI_setMapType}; + methodMap_["setMapStyle"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleCxxSpecJSI_setMapStyle}; + methodMap_["clearMapView"] = MethodMetadata {0, __hostFunction_NativeNavAutoModuleCxxSpecJSI_clearMapView}; + methodMap_["addCircle"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleCxxSpecJSI_addCircle}; + methodMap_["addMarker"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleCxxSpecJSI_addMarker}; + methodMap_["addPolyline"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleCxxSpecJSI_addPolyline}; + methodMap_["addPolygon"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleCxxSpecJSI_addPolygon}; + methodMap_["addGroundOverlay"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleCxxSpecJSI_addGroundOverlay}; + methodMap_["moveCamera"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleCxxSpecJSI_moveCamera}; + methodMap_["removeMarker"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleCxxSpecJSI_removeMarker}; + methodMap_["removePolyline"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleCxxSpecJSI_removePolyline}; + methodMap_["removePolygon"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleCxxSpecJSI_removePolygon}; + methodMap_["removeCircle"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleCxxSpecJSI_removeCircle}; + methodMap_["removeGroundOverlay"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleCxxSpecJSI_removeGroundOverlay}; + methodMap_["setIndoorEnabled"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleCxxSpecJSI_setIndoorEnabled}; + methodMap_["setTrafficEnabled"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleCxxSpecJSI_setTrafficEnabled}; + methodMap_["setCompassEnabled"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleCxxSpecJSI_setCompassEnabled}; + methodMap_["setMyLocationEnabled"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleCxxSpecJSI_setMyLocationEnabled}; + methodMap_["setBuildingsEnabled"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleCxxSpecJSI_setBuildingsEnabled}; + methodMap_["setZoomLevel"] = MethodMetadata {1, __hostFunction_NativeNavAutoModuleCxxSpecJSI_setZoomLevel}; + methodMap_["setMapPadding"] = MethodMetadata {4, __hostFunction_NativeNavAutoModuleCxxSpecJSI_setMapPadding}; + methodMap_["getCameraPosition"] = MethodMetadata {0, __hostFunction_NativeNavAutoModuleCxxSpecJSI_getCameraPosition}; + methodMap_["getMyLocation"] = MethodMetadata {0, __hostFunction_NativeNavAutoModuleCxxSpecJSI_getMyLocation}; + methodMap_["getUiSettings"] = MethodMetadata {0, __hostFunction_NativeNavAutoModuleCxxSpecJSI_getUiSettings}; + methodMap_["isMyLocationEnabled"] = MethodMetadata {0, __hostFunction_NativeNavAutoModuleCxxSpecJSI_isMyLocationEnabled}; +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_initializeNavigator(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->initializeNavigator( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asObject(rt), + count <= 1 ? throw jsi::JSError(rt, "Expected argument in position 1 to be passed") : args[1].asNumber() + ); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_cleanup(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->cleanup( + rt + ); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_setDestinations(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->setDestinations( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asObject(rt).asArray(rt), + count <= 1 || args[1].isUndefined() ? std::nullopt : std::make_optional(args[1].asObject(rt)), + count <= 2 || args[2].isUndefined() ? std::nullopt : std::make_optional(args[2].asObject(rt)) + ); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_continueToNextDestination(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->continueToNextDestination( + rt + ); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_clearDestinations(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->clearDestinations( + rt + ); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_startGuidance(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->startGuidance( + rt + ); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_stopGuidance(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->stopGuidance( + rt + ); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_setSpeedAlertOptions(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->setSpeedAlertOptions( + rt, + count <= 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt)) + ); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_setAbnormalTerminatingReportingEnabled(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->setAbnormalTerminatingReportingEnabled( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asBool() + ); + return jsi::Value::undefined(); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_setAudioGuidanceType(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->setAudioGuidanceType( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber() + ); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_setBackgroundLocationUpdatesEnabled(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->setBackgroundLocationUpdatesEnabled( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asBool() + ); + return jsi::Value::undefined(); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_setTurnByTurnLoggingEnabled(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->setTurnByTurnLoggingEnabled( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asBool() + ); + return jsi::Value::undefined(); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_areTermsAccepted(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->areTermsAccepted( + rt + ); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_getCurrentRouteSegment(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getCurrentRouteSegment( + rt + ); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_getRouteSegments(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getRouteSegments( + rt + ); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_getCurrentTimeAndDistance(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getCurrentTimeAndDistance( + rt + ); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_getTraveledPath(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getTraveledPath( + rt + ); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_getNavSDKVersion(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getNavSDKVersion( + rt + ); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_stopUpdatingLocation(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->stopUpdatingLocation( + rt + ); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_startUpdatingLocation(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->startUpdatingLocation( + rt + ); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_simulateLocation(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->simulateLocation( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asObject(rt) + ); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_resumeLocationSimulation(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->resumeLocationSimulation( + rt + ); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_pauseLocationSimulation(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->pauseLocationSimulation( + rt + ); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_simulateLocationsAlongExistingRoute(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->simulateLocationsAlongExistingRoute( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asObject(rt) + ); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_stopLocationSimulation(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->stopLocationSimulation( + rt + ); +} +static jsi::Value __hostFunction_NativeNavModuleCxxSpecJSI_resetTermsAccepted(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->resetTermsAccepted( + rt + ); + return jsi::Value::undefined(); +} + +NativeNavModuleCxxSpecJSI::NativeNavModuleCxxSpecJSI(std::shared_ptr jsInvoker) + : TurboModule("NavModule", jsInvoker) { + methodMap_["initializeNavigator"] = MethodMetadata {2, __hostFunction_NativeNavModuleCxxSpecJSI_initializeNavigator}; + methodMap_["cleanup"] = MethodMetadata {0, __hostFunction_NativeNavModuleCxxSpecJSI_cleanup}; + methodMap_["setDestinations"] = MethodMetadata {3, __hostFunction_NativeNavModuleCxxSpecJSI_setDestinations}; + methodMap_["continueToNextDestination"] = MethodMetadata {0, __hostFunction_NativeNavModuleCxxSpecJSI_continueToNextDestination}; + methodMap_["clearDestinations"] = MethodMetadata {0, __hostFunction_NativeNavModuleCxxSpecJSI_clearDestinations}; + methodMap_["startGuidance"] = MethodMetadata {0, __hostFunction_NativeNavModuleCxxSpecJSI_startGuidance}; + methodMap_["stopGuidance"] = MethodMetadata {0, __hostFunction_NativeNavModuleCxxSpecJSI_stopGuidance}; + methodMap_["setSpeedAlertOptions"] = MethodMetadata {1, __hostFunction_NativeNavModuleCxxSpecJSI_setSpeedAlertOptions}; + methodMap_["setAbnormalTerminatingReportingEnabled"] = MethodMetadata {1, __hostFunction_NativeNavModuleCxxSpecJSI_setAbnormalTerminatingReportingEnabled}; + methodMap_["setAudioGuidanceType"] = MethodMetadata {1, __hostFunction_NativeNavModuleCxxSpecJSI_setAudioGuidanceType}; + methodMap_["setBackgroundLocationUpdatesEnabled"] = MethodMetadata {1, __hostFunction_NativeNavModuleCxxSpecJSI_setBackgroundLocationUpdatesEnabled}; + methodMap_["setTurnByTurnLoggingEnabled"] = MethodMetadata {1, __hostFunction_NativeNavModuleCxxSpecJSI_setTurnByTurnLoggingEnabled}; + methodMap_["areTermsAccepted"] = MethodMetadata {0, __hostFunction_NativeNavModuleCxxSpecJSI_areTermsAccepted}; + methodMap_["getCurrentRouteSegment"] = MethodMetadata {0, __hostFunction_NativeNavModuleCxxSpecJSI_getCurrentRouteSegment}; + methodMap_["getRouteSegments"] = MethodMetadata {0, __hostFunction_NativeNavModuleCxxSpecJSI_getRouteSegments}; + methodMap_["getCurrentTimeAndDistance"] = MethodMetadata {0, __hostFunction_NativeNavModuleCxxSpecJSI_getCurrentTimeAndDistance}; + methodMap_["getTraveledPath"] = MethodMetadata {0, __hostFunction_NativeNavModuleCxxSpecJSI_getTraveledPath}; + methodMap_["getNavSDKVersion"] = MethodMetadata {0, __hostFunction_NativeNavModuleCxxSpecJSI_getNavSDKVersion}; + methodMap_["stopUpdatingLocation"] = MethodMetadata {0, __hostFunction_NativeNavModuleCxxSpecJSI_stopUpdatingLocation}; + methodMap_["startUpdatingLocation"] = MethodMetadata {0, __hostFunction_NativeNavModuleCxxSpecJSI_startUpdatingLocation}; + methodMap_["simulateLocation"] = MethodMetadata {1, __hostFunction_NativeNavModuleCxxSpecJSI_simulateLocation}; + methodMap_["resumeLocationSimulation"] = MethodMetadata {0, __hostFunction_NativeNavModuleCxxSpecJSI_resumeLocationSimulation}; + methodMap_["pauseLocationSimulation"] = MethodMetadata {0, __hostFunction_NativeNavModuleCxxSpecJSI_pauseLocationSimulation}; + methodMap_["simulateLocationsAlongExistingRoute"] = MethodMetadata {1, __hostFunction_NativeNavModuleCxxSpecJSI_simulateLocationsAlongExistingRoute}; + methodMap_["stopLocationSimulation"] = MethodMetadata {0, __hostFunction_NativeNavModuleCxxSpecJSI_stopLocationSimulation}; + methodMap_["resetTermsAccepted"] = MethodMetadata {0, __hostFunction_NativeNavModuleCxxSpecJSI_resetTermsAccepted}; +} +static jsi::Value __hostFunction_NativeNavViewModuleCxxSpecJSI_addCircle(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->addCircle( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber(), + count <= 1 ? throw jsi::JSError(rt, "Expected argument in position 1 to be passed") : args[1].asObject(rt) + ); +} +static jsi::Value __hostFunction_NativeNavViewModuleCxxSpecJSI_addMarker(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->addMarker( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber(), + count <= 1 ? throw jsi::JSError(rt, "Expected argument in position 1 to be passed") : args[1].asObject(rt) + ); +} +static jsi::Value __hostFunction_NativeNavViewModuleCxxSpecJSI_addPolyline(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->addPolyline( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber(), + count <= 1 ? throw jsi::JSError(rt, "Expected argument in position 1 to be passed") : args[1].asObject(rt) + ); +} +static jsi::Value __hostFunction_NativeNavViewModuleCxxSpecJSI_addPolygon(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->addPolygon( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber(), + count <= 1 ? throw jsi::JSError(rt, "Expected argument in position 1 to be passed") : args[1].asObject(rt) + ); +} +static jsi::Value __hostFunction_NativeNavViewModuleCxxSpecJSI_addGroundOverlay(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->addGroundOverlay( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber(), + count <= 1 ? throw jsi::JSError(rt, "Expected argument in position 1 to be passed") : args[1].asObject(rt) + ); +} +static jsi::Value __hostFunction_NativeNavViewModuleCxxSpecJSI_moveCamera(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->moveCamera( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber(), + count <= 1 ? throw jsi::JSError(rt, "Expected argument in position 1 to be passed") : args[1].asObject(rt) + ); +} +static jsi::Value __hostFunction_NativeNavViewModuleCxxSpecJSI_getCameraPosition(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getCameraPosition( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber() + ); +} +static jsi::Value __hostFunction_NativeNavViewModuleCxxSpecJSI_getMyLocation(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getMyLocation( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber() + ); +} +static jsi::Value __hostFunction_NativeNavViewModuleCxxSpecJSI_getUiSettings(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getUiSettings( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber() + ); +} +static jsi::Value __hostFunction_NativeNavViewModuleCxxSpecJSI_isMyLocationEnabled(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->isMyLocationEnabled( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber() + ); +} +static jsi::Value __hostFunction_NativeNavViewModuleCxxSpecJSI_showRouteOverview(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->showRouteOverview( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber() + ); +} +static jsi::Value __hostFunction_NativeNavViewModuleCxxSpecJSI_clearMapView(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->clearMapView( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber() + ); +} +static jsi::Value __hostFunction_NativeNavViewModuleCxxSpecJSI_removeMarker(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->removeMarker( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber(), + count <= 1 ? throw jsi::JSError(rt, "Expected argument in position 1 to be passed") : args[1].asString(rt) + ); +} +static jsi::Value __hostFunction_NativeNavViewModuleCxxSpecJSI_removePolyline(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->removePolyline( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber(), + count <= 1 ? throw jsi::JSError(rt, "Expected argument in position 1 to be passed") : args[1].asString(rt) + ); +} +static jsi::Value __hostFunction_NativeNavViewModuleCxxSpecJSI_removePolygon(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->removePolygon( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber(), + count <= 1 ? throw jsi::JSError(rt, "Expected argument in position 1 to be passed") : args[1].asString(rt) + ); +} +static jsi::Value __hostFunction_NativeNavViewModuleCxxSpecJSI_removeCircle(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->removeCircle( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber(), + count <= 1 ? throw jsi::JSError(rt, "Expected argument in position 1 to be passed") : args[1].asString(rt) + ); +} +static jsi::Value __hostFunction_NativeNavViewModuleCxxSpecJSI_removeGroundOverlay(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->removeGroundOverlay( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber(), + count <= 1 ? throw jsi::JSError(rt, "Expected argument in position 1 to be passed") : args[1].asString(rt) + ); +} +static jsi::Value __hostFunction_NativeNavViewModuleCxxSpecJSI_setZoomLevel(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->setZoomLevel( + rt, + count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber(), + count <= 1 ? throw jsi::JSError(rt, "Expected argument in position 1 to be passed") : args[1].asNumber() + ); +} + +NativeNavViewModuleCxxSpecJSI::NativeNavViewModuleCxxSpecJSI(std::shared_ptr jsInvoker) + : TurboModule("NavViewModule", jsInvoker) { + methodMap_["addCircle"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleCxxSpecJSI_addCircle}; + methodMap_["addMarker"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleCxxSpecJSI_addMarker}; + methodMap_["addPolyline"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleCxxSpecJSI_addPolyline}; + methodMap_["addPolygon"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleCxxSpecJSI_addPolygon}; + methodMap_["addGroundOverlay"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleCxxSpecJSI_addGroundOverlay}; + methodMap_["moveCamera"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleCxxSpecJSI_moveCamera}; + methodMap_["getCameraPosition"] = MethodMetadata {1, __hostFunction_NativeNavViewModuleCxxSpecJSI_getCameraPosition}; + methodMap_["getMyLocation"] = MethodMetadata {1, __hostFunction_NativeNavViewModuleCxxSpecJSI_getMyLocation}; + methodMap_["getUiSettings"] = MethodMetadata {1, __hostFunction_NativeNavViewModuleCxxSpecJSI_getUiSettings}; + methodMap_["isMyLocationEnabled"] = MethodMetadata {1, __hostFunction_NativeNavViewModuleCxxSpecJSI_isMyLocationEnabled}; + methodMap_["showRouteOverview"] = MethodMetadata {1, __hostFunction_NativeNavViewModuleCxxSpecJSI_showRouteOverview}; + methodMap_["clearMapView"] = MethodMetadata {1, __hostFunction_NativeNavViewModuleCxxSpecJSI_clearMapView}; + methodMap_["removeMarker"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleCxxSpecJSI_removeMarker}; + methodMap_["removePolyline"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleCxxSpecJSI_removePolyline}; + methodMap_["removePolygon"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleCxxSpecJSI_removePolygon}; + methodMap_["removeCircle"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleCxxSpecJSI_removeCircle}; + methodMap_["removeGroundOverlay"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleCxxSpecJSI_removeGroundOverlay}; + methodMap_["setZoomLevel"] = MethodMetadata {2, __hostFunction_NativeNavViewModuleCxxSpecJSI_setZoomLevel}; +} + + +} // namespace facebook::react diff --git a/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/RNNavigationSdkSpecJSI.h b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/RNNavigationSdkSpecJSI.h new file mode 100644 index 00000000..22311602 --- /dev/null +++ b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/RNNavigationSdkSpecJSI.h @@ -0,0 +1,2864 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateModuleH.js + */ + +#pragma once + +#include +#include + +namespace facebook::react { + + + +#pragma mark - NativeNavAutoModuleCameraPositionSpec + +template +struct NativeNavAutoModuleCameraPositionSpec { + P0 target; + P1 bearing; + P2 tilt; + P3 zoom; + bool operator==(const NativeNavAutoModuleCameraPositionSpec &other) const { + return target == other.target && bearing == other.bearing && tilt == other.tilt && zoom == other.zoom; + } +}; + +template +struct NativeNavAutoModuleCameraPositionSpecBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "target"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "bearing"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "tilt"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "zoom"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static std::optional targetToJs(jsi::Runtime &rt, decltype(types.target) value) { + return bridging::toJs(rt, value); + } + + static std::optional bearingToJs(jsi::Runtime &rt, decltype(types.bearing) value) { + return bridging::toJs(rt, value); + } + + static std::optional tiltToJs(jsi::Runtime &rt, decltype(types.tilt) value) { + return bridging::toJs(rt, value); + } + + static std::optional zoomToJs(jsi::Runtime &rt, decltype(types.zoom) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + if (value.target) { + result.setProperty(rt, "target", bridging::toJs(rt, value.target.value(), jsInvoker)); + } + if (value.bearing) { + result.setProperty(rt, "bearing", bridging::toJs(rt, value.bearing.value(), jsInvoker)); + } + if (value.tilt) { + result.setProperty(rt, "tilt", bridging::toJs(rt, value.tilt.value(), jsInvoker)); + } + if (value.zoom) { + result.setProperty(rt, "zoom", bridging::toJs(rt, value.zoom.value(), jsInvoker)); + } + return result; + } +}; + + + +#pragma mark - NativeNavAutoModuleCircleOptionsSpec + +template +struct NativeNavAutoModuleCircleOptionsSpec { + P0 center; + P1 id; + P2 radius; + P3 strokeWidth; + P4 strokeColor; + P5 fillColor; + P6 clickable; + P7 visible; + P8 zIndex; + bool operator==(const NativeNavAutoModuleCircleOptionsSpec &other) const { + return center == other.center && id == other.id && radius == other.radius && strokeWidth == other.strokeWidth && strokeColor == other.strokeColor && fillColor == other.fillColor && clickable == other.clickable && visible == other.visible && zIndex == other.zIndex; + } +}; + +template +struct NativeNavAutoModuleCircleOptionsSpecBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "center"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "id"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "radius"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "strokeWidth"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "strokeColor"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "fillColor"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "clickable"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "visible"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "zIndex"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::Object centerToJs(jsi::Runtime &rt, decltype(types.center) value) { + return bridging::toJs(rt, value); + } + + static std::optional idToJs(jsi::Runtime &rt, decltype(types.id) value) { + return bridging::toJs(rt, value); + } + + static double radiusToJs(jsi::Runtime &rt, decltype(types.radius) value) { + return bridging::toJs(rt, value); + } + + static std::optional strokeWidthToJs(jsi::Runtime &rt, decltype(types.strokeWidth) value) { + return bridging::toJs(rt, value); + } + + static std::optional strokeColorToJs(jsi::Runtime &rt, decltype(types.strokeColor) value) { + return bridging::toJs(rt, value); + } + + static std::optional fillColorToJs(jsi::Runtime &rt, decltype(types.fillColor) value) { + return bridging::toJs(rt, value); + } + + static std::optional clickableToJs(jsi::Runtime &rt, decltype(types.clickable) value) { + return bridging::toJs(rt, value); + } + + static std::optional visibleToJs(jsi::Runtime &rt, decltype(types.visible) value) { + return bridging::toJs(rt, value); + } + + static std::optional zIndexToJs(jsi::Runtime &rt, decltype(types.zIndex) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "center", bridging::toJs(rt, value.center, jsInvoker)); + if (value.id) { + result.setProperty(rt, "id", bridging::toJs(rt, value.id.value(), jsInvoker)); + } + result.setProperty(rt, "radius", bridging::toJs(rt, value.radius, jsInvoker)); + if (value.strokeWidth) { + result.setProperty(rt, "strokeWidth", bridging::toJs(rt, value.strokeWidth.value(), jsInvoker)); + } + if (value.strokeColor) { + result.setProperty(rt, "strokeColor", bridging::toJs(rt, value.strokeColor.value(), jsInvoker)); + } + if (value.fillColor) { + result.setProperty(rt, "fillColor", bridging::toJs(rt, value.fillColor.value(), jsInvoker)); + } + if (value.clickable) { + result.setProperty(rt, "clickable", bridging::toJs(rt, value.clickable.value(), jsInvoker)); + } + if (value.visible) { + result.setProperty(rt, "visible", bridging::toJs(rt, value.visible.value(), jsInvoker)); + } + if (value.zIndex) { + result.setProperty(rt, "zIndex", bridging::toJs(rt, value.zIndex.value(), jsInvoker)); + } + return result; + } +}; + + + +#pragma mark - NativeNavAutoModuleCustomNavigationAutoEventSpec + +template +struct NativeNavAutoModuleCustomNavigationAutoEventSpec { + P0 type; + P1 data; + bool operator==(const NativeNavAutoModuleCustomNavigationAutoEventSpec &other) const { + return type == other.type && data == other.data; + } +}; + +template +struct NativeNavAutoModuleCustomNavigationAutoEventSpecBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "type"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "data"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::String typeToJs(jsi::Runtime &rt, decltype(types.type) value) { + return bridging::toJs(rt, value); + } + + static std::optional dataToJs(jsi::Runtime &rt, decltype(types.data) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "type", bridging::toJs(rt, value.type, jsInvoker)); + result.setProperty(rt, "data", bridging::toJs(rt, value.data, jsInvoker)); + return result; + } +}; + + + +#pragma mark - NativeNavAutoModuleMarkerOptionsSpec + +template +struct NativeNavAutoModuleMarkerOptionsSpec { + P0 position; + P1 id; + P2 imgPath; + P3 title; + P4 snippet; + P5 alpha; + P6 rotation; + P7 draggable; + P8 flat; + P9 visible; + P10 zIndex; + bool operator==(const NativeNavAutoModuleMarkerOptionsSpec &other) const { + return position == other.position && id == other.id && imgPath == other.imgPath && title == other.title && snippet == other.snippet && alpha == other.alpha && rotation == other.rotation && draggable == other.draggable && flat == other.flat && visible == other.visible && zIndex == other.zIndex; + } +}; + +template +struct NativeNavAutoModuleMarkerOptionsSpecBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "position"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "id"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "imgPath"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "title"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "snippet"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "alpha"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "rotation"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "draggable"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "flat"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "visible"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "zIndex"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::Object positionToJs(jsi::Runtime &rt, decltype(types.position) value) { + return bridging::toJs(rt, value); + } + + static std::optional idToJs(jsi::Runtime &rt, decltype(types.id) value) { + return bridging::toJs(rt, value); + } + + static std::optional imgPathToJs(jsi::Runtime &rt, decltype(types.imgPath) value) { + return bridging::toJs(rt, value); + } + + static std::optional titleToJs(jsi::Runtime &rt, decltype(types.title) value) { + return bridging::toJs(rt, value); + } + + static std::optional snippetToJs(jsi::Runtime &rt, decltype(types.snippet) value) { + return bridging::toJs(rt, value); + } + + static std::optional alphaToJs(jsi::Runtime &rt, decltype(types.alpha) value) { + return bridging::toJs(rt, value); + } + + static std::optional rotationToJs(jsi::Runtime &rt, decltype(types.rotation) value) { + return bridging::toJs(rt, value); + } + + static std::optional draggableToJs(jsi::Runtime &rt, decltype(types.draggable) value) { + return bridging::toJs(rt, value); + } + + static std::optional flatToJs(jsi::Runtime &rt, decltype(types.flat) value) { + return bridging::toJs(rt, value); + } + + static std::optional visibleToJs(jsi::Runtime &rt, decltype(types.visible) value) { + return bridging::toJs(rt, value); + } + + static std::optional zIndexToJs(jsi::Runtime &rt, decltype(types.zIndex) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "position", bridging::toJs(rt, value.position, jsInvoker)); + if (value.id) { + result.setProperty(rt, "id", bridging::toJs(rt, value.id.value(), jsInvoker)); + } + if (value.imgPath) { + result.setProperty(rt, "imgPath", bridging::toJs(rt, value.imgPath.value(), jsInvoker)); + } + if (value.title) { + result.setProperty(rt, "title", bridging::toJs(rt, value.title.value(), jsInvoker)); + } + if (value.snippet) { + result.setProperty(rt, "snippet", bridging::toJs(rt, value.snippet.value(), jsInvoker)); + } + if (value.alpha) { + result.setProperty(rt, "alpha", bridging::toJs(rt, value.alpha.value(), jsInvoker)); + } + if (value.rotation) { + result.setProperty(rt, "rotation", bridging::toJs(rt, value.rotation.value(), jsInvoker)); + } + if (value.draggable) { + result.setProperty(rt, "draggable", bridging::toJs(rt, value.draggable.value(), jsInvoker)); + } + if (value.flat) { + result.setProperty(rt, "flat", bridging::toJs(rt, value.flat.value(), jsInvoker)); + } + if (value.visible) { + result.setProperty(rt, "visible", bridging::toJs(rt, value.visible.value(), jsInvoker)); + } + if (value.zIndex) { + result.setProperty(rt, "zIndex", bridging::toJs(rt, value.zIndex.value(), jsInvoker)); + } + return result; + } +}; + + + +#pragma mark - NativeNavAutoModulePolygonOptionsSpec + +template +struct NativeNavAutoModulePolygonOptionsSpec { + P0 points; + P1 id; + P2 holes; + P3 strokeWidth; + P4 strokeColor; + P5 fillColor; + P6 geodesic; + P7 clickable; + P8 visible; + P9 zIndex; + bool operator==(const NativeNavAutoModulePolygonOptionsSpec &other) const { + return points == other.points && id == other.id && holes == other.holes && strokeWidth == other.strokeWidth && strokeColor == other.strokeColor && fillColor == other.fillColor && geodesic == other.geodesic && clickable == other.clickable && visible == other.visible && zIndex == other.zIndex; + } +}; + +template +struct NativeNavAutoModulePolygonOptionsSpecBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "points"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "id"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "holes"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "strokeWidth"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "strokeColor"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "fillColor"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "geodesic"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "clickable"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "visible"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "zIndex"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::Array pointsToJs(jsi::Runtime &rt, decltype(types.points) value) { + return bridging::toJs(rt, value); + } + + static std::optional idToJs(jsi::Runtime &rt, decltype(types.id) value) { + return bridging::toJs(rt, value); + } + + static jsi::Array holesToJs(jsi::Runtime &rt, decltype(types.holes) value) { + return bridging::toJs(rt, value); + } + + static std::optional strokeWidthToJs(jsi::Runtime &rt, decltype(types.strokeWidth) value) { + return bridging::toJs(rt, value); + } + + static std::optional strokeColorToJs(jsi::Runtime &rt, decltype(types.strokeColor) value) { + return bridging::toJs(rt, value); + } + + static std::optional fillColorToJs(jsi::Runtime &rt, decltype(types.fillColor) value) { + return bridging::toJs(rt, value); + } + + static std::optional geodesicToJs(jsi::Runtime &rt, decltype(types.geodesic) value) { + return bridging::toJs(rt, value); + } + + static std::optional clickableToJs(jsi::Runtime &rt, decltype(types.clickable) value) { + return bridging::toJs(rt, value); + } + + static std::optional visibleToJs(jsi::Runtime &rt, decltype(types.visible) value) { + return bridging::toJs(rt, value); + } + + static std::optional zIndexToJs(jsi::Runtime &rt, decltype(types.zIndex) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "points", bridging::toJs(rt, value.points, jsInvoker)); + if (value.id) { + result.setProperty(rt, "id", bridging::toJs(rt, value.id.value(), jsInvoker)); + } + result.setProperty(rt, "holes", bridging::toJs(rt, value.holes, jsInvoker)); + if (value.strokeWidth) { + result.setProperty(rt, "strokeWidth", bridging::toJs(rt, value.strokeWidth.value(), jsInvoker)); + } + if (value.strokeColor) { + result.setProperty(rt, "strokeColor", bridging::toJs(rt, value.strokeColor.value(), jsInvoker)); + } + if (value.fillColor) { + result.setProperty(rt, "fillColor", bridging::toJs(rt, value.fillColor.value(), jsInvoker)); + } + if (value.geodesic) { + result.setProperty(rt, "geodesic", bridging::toJs(rt, value.geodesic.value(), jsInvoker)); + } + if (value.clickable) { + result.setProperty(rt, "clickable", bridging::toJs(rt, value.clickable.value(), jsInvoker)); + } + if (value.visible) { + result.setProperty(rt, "visible", bridging::toJs(rt, value.visible.value(), jsInvoker)); + } + if (value.zIndex) { + result.setProperty(rt, "zIndex", bridging::toJs(rt, value.zIndex.value(), jsInvoker)); + } + return result; + } +}; + + + +#pragma mark - NativeNavAutoModulePolylineOptionsSpec + +template +struct NativeNavAutoModulePolylineOptionsSpec { + P0 points; + P1 id; + P2 color; + P3 width; + P4 clickable; + P5 visible; + P6 zIndex; + bool operator==(const NativeNavAutoModulePolylineOptionsSpec &other) const { + return points == other.points && id == other.id && color == other.color && width == other.width && clickable == other.clickable && visible == other.visible && zIndex == other.zIndex; + } +}; + +template +struct NativeNavAutoModulePolylineOptionsSpecBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "points"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "id"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "color"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "width"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "clickable"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "visible"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "zIndex"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::Array pointsToJs(jsi::Runtime &rt, decltype(types.points) value) { + return bridging::toJs(rt, value); + } + + static std::optional idToJs(jsi::Runtime &rt, decltype(types.id) value) { + return bridging::toJs(rt, value); + } + + static std::optional colorToJs(jsi::Runtime &rt, decltype(types.color) value) { + return bridging::toJs(rt, value); + } + + static std::optional widthToJs(jsi::Runtime &rt, decltype(types.width) value) { + return bridging::toJs(rt, value); + } + + static std::optional clickableToJs(jsi::Runtime &rt, decltype(types.clickable) value) { + return bridging::toJs(rt, value); + } + + static std::optional visibleToJs(jsi::Runtime &rt, decltype(types.visible) value) { + return bridging::toJs(rt, value); + } + + static std::optional zIndexToJs(jsi::Runtime &rt, decltype(types.zIndex) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "points", bridging::toJs(rt, value.points, jsInvoker)); + if (value.id) { + result.setProperty(rt, "id", bridging::toJs(rt, value.id.value(), jsInvoker)); + } + if (value.color) { + result.setProperty(rt, "color", bridging::toJs(rt, value.color.value(), jsInvoker)); + } + if (value.width) { + result.setProperty(rt, "width", bridging::toJs(rt, value.width.value(), jsInvoker)); + } + if (value.clickable) { + result.setProperty(rt, "clickable", bridging::toJs(rt, value.clickable.value(), jsInvoker)); + } + if (value.visible) { + result.setProperty(rt, "visible", bridging::toJs(rt, value.visible.value(), jsInvoker)); + } + if (value.zIndex) { + result.setProperty(rt, "zIndex", bridging::toJs(rt, value.zIndex.value(), jsInvoker)); + } + return result; + } +}; + +class JSI_EXPORT NativeNavAutoModuleCxxSpecJSI : public TurboModule { +protected: + NativeNavAutoModuleCxxSpecJSI(std::shared_ptr jsInvoker); + +public: + virtual jsi::Value isAutoScreenAvailable(jsi::Runtime &rt) = 0; + virtual void setMapType(jsi::Runtime &rt, double mapType) = 0; + virtual void setMapStyle(jsi::Runtime &rt, jsi::String mapStyle) = 0; + virtual jsi::Value clearMapView(jsi::Runtime &rt) = 0; + virtual jsi::Value addCircle(jsi::Runtime &rt, jsi::Object options) = 0; + virtual jsi::Value addMarker(jsi::Runtime &rt, jsi::Object options) = 0; + virtual jsi::Value addPolyline(jsi::Runtime &rt, jsi::Object options) = 0; + virtual jsi::Value addPolygon(jsi::Runtime &rt, jsi::Object options) = 0; + virtual jsi::Value addGroundOverlay(jsi::Runtime &rt, jsi::Object options) = 0; + virtual jsi::Value moveCamera(jsi::Runtime &rt, jsi::Object cameraPosition) = 0; + virtual jsi::Value removeMarker(jsi::Runtime &rt, jsi::String id) = 0; + virtual jsi::Value removePolyline(jsi::Runtime &rt, jsi::String id) = 0; + virtual jsi::Value removePolygon(jsi::Runtime &rt, jsi::String id) = 0; + virtual jsi::Value removeCircle(jsi::Runtime &rt, jsi::String id) = 0; + virtual jsi::Value removeGroundOverlay(jsi::Runtime &rt, jsi::String id) = 0; + virtual void setIndoorEnabled(jsi::Runtime &rt, bool isOn) = 0; + virtual void setTrafficEnabled(jsi::Runtime &rt, bool isOn) = 0; + virtual void setCompassEnabled(jsi::Runtime &rt, bool isOn) = 0; + virtual void setMyLocationEnabled(jsi::Runtime &rt, bool isOn) = 0; + virtual void setBuildingsEnabled(jsi::Runtime &rt, bool isOn) = 0; + virtual jsi::Value setZoomLevel(jsi::Runtime &rt, double zoomLevel) = 0; + virtual void setMapPadding(jsi::Runtime &rt, double top, double left, double bottom, double right) = 0; + virtual jsi::Value getCameraPosition(jsi::Runtime &rt) = 0; + virtual jsi::Value getMyLocation(jsi::Runtime &rt) = 0; + virtual jsi::Value getUiSettings(jsi::Runtime &rt) = 0; + virtual jsi::Value isMyLocationEnabled(jsi::Runtime &rt) = 0; + +}; + +template +class JSI_EXPORT NativeNavAutoModuleCxxSpec : public TurboModule { +public: + jsi::Value create(jsi::Runtime &rt, const jsi::PropNameID &propName) override { + return delegate_.create(rt, propName); + } + + std::vector getPropertyNames(jsi::Runtime& runtime) override { + return delegate_.getPropertyNames(runtime); + } + + static constexpr std::string_view kModuleName = "NavAutoModule"; + +protected: + NativeNavAutoModuleCxxSpec(std::shared_ptr jsInvoker) + : TurboModule(std::string{NativeNavAutoModuleCxxSpec::kModuleName}, jsInvoker), + delegate_(reinterpret_cast(this), jsInvoker) {} + + template void emitOnAutoScreenAvailabilityChanged(OnAutoScreenAvailabilityChangedType value) { + static_assert(bridging::supportsFromJs, "value cannnot be converted to bool"); + static_cast&>(*delegate_.eventEmitterMap_["onAutoScreenAvailabilityChanged"]).emit([jsInvoker = jsInvoker_, eventValue = value](jsi::Runtime& rt) -> jsi::Value { + return bridging::toJs(rt, eventValue, jsInvoker); + }); + } + + template void emitOnCustomNavigationAutoEvent(OnCustomNavigationAutoEventType value) { + static_assert(bridging::supportsFromJs, "value cannnot be converted to jsi::Object"); + static_cast&>(*delegate_.eventEmitterMap_["onCustomNavigationAutoEvent"]).emit([jsInvoker = jsInvoker_, eventValue = value](jsi::Runtime& rt) -> jsi::Value { + return bridging::toJs(rt, eventValue, jsInvoker); + }); + } + +private: + class Delegate : public NativeNavAutoModuleCxxSpecJSI { + public: + Delegate(T *instance, std::shared_ptr jsInvoker) : + NativeNavAutoModuleCxxSpecJSI(std::move(jsInvoker)), instance_(instance) { + eventEmitterMap_["onAutoScreenAvailabilityChanged"] = std::make_shared>(); + eventEmitterMap_["onCustomNavigationAutoEvent"] = std::make_shared>(); + } + + jsi::Value isAutoScreenAvailable(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::isAutoScreenAvailable) == 1, + "Expected isAutoScreenAvailable(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::isAutoScreenAvailable, jsInvoker_, instance_); + } + void setMapType(jsi::Runtime &rt, double mapType) override { + static_assert( + bridging::getParameterCount(&T::setMapType) == 2, + "Expected setMapType(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::setMapType, jsInvoker_, instance_, std::move(mapType)); + } + void setMapStyle(jsi::Runtime &rt, jsi::String mapStyle) override { + static_assert( + bridging::getParameterCount(&T::setMapStyle) == 2, + "Expected setMapStyle(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::setMapStyle, jsInvoker_, instance_, std::move(mapStyle)); + } + jsi::Value clearMapView(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::clearMapView) == 1, + "Expected clearMapView(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::clearMapView, jsInvoker_, instance_); + } + jsi::Value addCircle(jsi::Runtime &rt, jsi::Object options) override { + static_assert( + bridging::getParameterCount(&T::addCircle) == 2, + "Expected addCircle(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::addCircle, jsInvoker_, instance_, std::move(options)); + } + jsi::Value addMarker(jsi::Runtime &rt, jsi::Object options) override { + static_assert( + bridging::getParameterCount(&T::addMarker) == 2, + "Expected addMarker(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::addMarker, jsInvoker_, instance_, std::move(options)); + } + jsi::Value addPolyline(jsi::Runtime &rt, jsi::Object options) override { + static_assert( + bridging::getParameterCount(&T::addPolyline) == 2, + "Expected addPolyline(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::addPolyline, jsInvoker_, instance_, std::move(options)); + } + jsi::Value addPolygon(jsi::Runtime &rt, jsi::Object options) override { + static_assert( + bridging::getParameterCount(&T::addPolygon) == 2, + "Expected addPolygon(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::addPolygon, jsInvoker_, instance_, std::move(options)); + } + jsi::Value addGroundOverlay(jsi::Runtime &rt, jsi::Object options) override { + static_assert( + bridging::getParameterCount(&T::addGroundOverlay) == 2, + "Expected addGroundOverlay(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::addGroundOverlay, jsInvoker_, instance_, std::move(options)); + } + jsi::Value moveCamera(jsi::Runtime &rt, jsi::Object cameraPosition) override { + static_assert( + bridging::getParameterCount(&T::moveCamera) == 2, + "Expected moveCamera(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::moveCamera, jsInvoker_, instance_, std::move(cameraPosition)); + } + jsi::Value removeMarker(jsi::Runtime &rt, jsi::String id) override { + static_assert( + bridging::getParameterCount(&T::removeMarker) == 2, + "Expected removeMarker(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::removeMarker, jsInvoker_, instance_, std::move(id)); + } + jsi::Value removePolyline(jsi::Runtime &rt, jsi::String id) override { + static_assert( + bridging::getParameterCount(&T::removePolyline) == 2, + "Expected removePolyline(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::removePolyline, jsInvoker_, instance_, std::move(id)); + } + jsi::Value removePolygon(jsi::Runtime &rt, jsi::String id) override { + static_assert( + bridging::getParameterCount(&T::removePolygon) == 2, + "Expected removePolygon(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::removePolygon, jsInvoker_, instance_, std::move(id)); + } + jsi::Value removeCircle(jsi::Runtime &rt, jsi::String id) override { + static_assert( + bridging::getParameterCount(&T::removeCircle) == 2, + "Expected removeCircle(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::removeCircle, jsInvoker_, instance_, std::move(id)); + } + jsi::Value removeGroundOverlay(jsi::Runtime &rt, jsi::String id) override { + static_assert( + bridging::getParameterCount(&T::removeGroundOverlay) == 2, + "Expected removeGroundOverlay(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::removeGroundOverlay, jsInvoker_, instance_, std::move(id)); + } + void setIndoorEnabled(jsi::Runtime &rt, bool isOn) override { + static_assert( + bridging::getParameterCount(&T::setIndoorEnabled) == 2, + "Expected setIndoorEnabled(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::setIndoorEnabled, jsInvoker_, instance_, std::move(isOn)); + } + void setTrafficEnabled(jsi::Runtime &rt, bool isOn) override { + static_assert( + bridging::getParameterCount(&T::setTrafficEnabled) == 2, + "Expected setTrafficEnabled(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::setTrafficEnabled, jsInvoker_, instance_, std::move(isOn)); + } + void setCompassEnabled(jsi::Runtime &rt, bool isOn) override { + static_assert( + bridging::getParameterCount(&T::setCompassEnabled) == 2, + "Expected setCompassEnabled(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::setCompassEnabled, jsInvoker_, instance_, std::move(isOn)); + } + void setMyLocationEnabled(jsi::Runtime &rt, bool isOn) override { + static_assert( + bridging::getParameterCount(&T::setMyLocationEnabled) == 2, + "Expected setMyLocationEnabled(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::setMyLocationEnabled, jsInvoker_, instance_, std::move(isOn)); + } + void setBuildingsEnabled(jsi::Runtime &rt, bool isOn) override { + static_assert( + bridging::getParameterCount(&T::setBuildingsEnabled) == 2, + "Expected setBuildingsEnabled(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::setBuildingsEnabled, jsInvoker_, instance_, std::move(isOn)); + } + jsi::Value setZoomLevel(jsi::Runtime &rt, double zoomLevel) override { + static_assert( + bridging::getParameterCount(&T::setZoomLevel) == 2, + "Expected setZoomLevel(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::setZoomLevel, jsInvoker_, instance_, std::move(zoomLevel)); + } + void setMapPadding(jsi::Runtime &rt, double top, double left, double bottom, double right) override { + static_assert( + bridging::getParameterCount(&T::setMapPadding) == 5, + "Expected setMapPadding(...) to have 5 parameters"); + + return bridging::callFromJs( + rt, &T::setMapPadding, jsInvoker_, instance_, std::move(top), std::move(left), std::move(bottom), std::move(right)); + } + jsi::Value getCameraPosition(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::getCameraPosition) == 1, + "Expected getCameraPosition(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::getCameraPosition, jsInvoker_, instance_); + } + jsi::Value getMyLocation(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::getMyLocation) == 1, + "Expected getMyLocation(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::getMyLocation, jsInvoker_, instance_); + } + jsi::Value getUiSettings(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::getUiSettings) == 1, + "Expected getUiSettings(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::getUiSettings, jsInvoker_, instance_); + } + jsi::Value isMyLocationEnabled(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::isMyLocationEnabled) == 1, + "Expected isMyLocationEnabled(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::isMyLocationEnabled, jsInvoker_, instance_); + } + + private: + friend class NativeNavAutoModuleCxxSpec; + T *instance_; + }; + + Delegate delegate_; +}; + + +#pragma mark - NativeNavModuleNavigationInitializationStatusSpec + +enum class NativeNavModuleNavigationInitializationStatusSpec { UNKNOWN, NOT_AUTHORIZED, TERMS_NOT_ACCEPTED, NETWORK_ERROR, LOCATION_PERMISSION_MISSING }; + +template <> +struct Bridging { + static NativeNavModuleNavigationInitializationStatusSpec fromJs(jsi::Runtime &rt, const jsi::String &rawValue) { + std::string value = rawValue.utf8(rt); + if (value == "UNKNOWN") { + return NativeNavModuleNavigationInitializationStatusSpec::UNKNOWN; + } else if (value == "NOT_AUTHORIZED") { + return NativeNavModuleNavigationInitializationStatusSpec::NOT_AUTHORIZED; + } else if (value == "TERMS_NOT_ACCEPTED") { + return NativeNavModuleNavigationInitializationStatusSpec::TERMS_NOT_ACCEPTED; + } else if (value == "NETWORK_ERROR") { + return NativeNavModuleNavigationInitializationStatusSpec::NETWORK_ERROR; + } else if (value == "LOCATION_PERMISSION_MISSING") { + return NativeNavModuleNavigationInitializationStatusSpec::LOCATION_PERMISSION_MISSING; + } else { + throw jsi::JSError(rt, "No appropriate enum member found for value"); + } + } + + static jsi::String toJs(jsi::Runtime &rt, NativeNavModuleNavigationInitializationStatusSpec value) { + if (value == NativeNavModuleNavigationInitializationStatusSpec::UNKNOWN) { + return bridging::toJs(rt, "UNKNOWN"); + } else if (value == NativeNavModuleNavigationInitializationStatusSpec::NOT_AUTHORIZED) { + return bridging::toJs(rt, "NOT_AUTHORIZED"); + } else if (value == NativeNavModuleNavigationInitializationStatusSpec::TERMS_NOT_ACCEPTED) { + return bridging::toJs(rt, "TERMS_NOT_ACCEPTED"); + } else if (value == NativeNavModuleNavigationInitializationStatusSpec::NETWORK_ERROR) { + return bridging::toJs(rt, "NETWORK_ERROR"); + } else if (value == NativeNavModuleNavigationInitializationStatusSpec::LOCATION_PERMISSION_MISSING) { + return bridging::toJs(rt, "LOCATION_PERMISSION_MISSING"); + } else { + throw jsi::JSError(rt, "No appropriate enum member found for enum value"); + } + } +}; + +#pragma mark - NativeNavModuleRouteStatusSpec + +enum class NativeNavModuleRouteStatusSpec { OK, NO_ROUTE_FOUND, NETWORK_ERROR, QUOTA_CHECK_FAILED, ROUTE_CANCELED, LOCATION_DISABLED, LOCATION_UNKNOWN, WAYPOINT_ERROR, INVALID_PLACE_ID, UNKNOWN }; + +template <> +struct Bridging { + static NativeNavModuleRouteStatusSpec fromJs(jsi::Runtime &rt, const jsi::String &rawValue) { + std::string value = rawValue.utf8(rt); + if (value == "OK") { + return NativeNavModuleRouteStatusSpec::OK; + } else if (value == "NO_ROUTE_FOUND") { + return NativeNavModuleRouteStatusSpec::NO_ROUTE_FOUND; + } else if (value == "NETWORK_ERROR") { + return NativeNavModuleRouteStatusSpec::NETWORK_ERROR; + } else if (value == "QUOTA_CHECK_FAILED") { + return NativeNavModuleRouteStatusSpec::QUOTA_CHECK_FAILED; + } else if (value == "ROUTE_CANCELED") { + return NativeNavModuleRouteStatusSpec::ROUTE_CANCELED; + } else if (value == "LOCATION_DISABLED") { + return NativeNavModuleRouteStatusSpec::LOCATION_DISABLED; + } else if (value == "LOCATION_UNKNOWN") { + return NativeNavModuleRouteStatusSpec::LOCATION_UNKNOWN; + } else if (value == "WAYPOINT_ERROR") { + return NativeNavModuleRouteStatusSpec::WAYPOINT_ERROR; + } else if (value == "INVALID_PLACE_ID") { + return NativeNavModuleRouteStatusSpec::INVALID_PLACE_ID; + } else if (value == "UNKNOWN") { + return NativeNavModuleRouteStatusSpec::UNKNOWN; + } else { + throw jsi::JSError(rt, "No appropriate enum member found for value"); + } + } + + static jsi::String toJs(jsi::Runtime &rt, NativeNavModuleRouteStatusSpec value) { + if (value == NativeNavModuleRouteStatusSpec::OK) { + return bridging::toJs(rt, "OK"); + } else if (value == NativeNavModuleRouteStatusSpec::NO_ROUTE_FOUND) { + return bridging::toJs(rt, "NO_ROUTE_FOUND"); + } else if (value == NativeNavModuleRouteStatusSpec::NETWORK_ERROR) { + return bridging::toJs(rt, "NETWORK_ERROR"); + } else if (value == NativeNavModuleRouteStatusSpec::QUOTA_CHECK_FAILED) { + return bridging::toJs(rt, "QUOTA_CHECK_FAILED"); + } else if (value == NativeNavModuleRouteStatusSpec::ROUTE_CANCELED) { + return bridging::toJs(rt, "ROUTE_CANCELED"); + } else if (value == NativeNavModuleRouteStatusSpec::LOCATION_DISABLED) { + return bridging::toJs(rt, "LOCATION_DISABLED"); + } else if (value == NativeNavModuleRouteStatusSpec::LOCATION_UNKNOWN) { + return bridging::toJs(rt, "LOCATION_UNKNOWN"); + } else if (value == NativeNavModuleRouteStatusSpec::WAYPOINT_ERROR) { + return bridging::toJs(rt, "WAYPOINT_ERROR"); + } else if (value == NativeNavModuleRouteStatusSpec::INVALID_PLACE_ID) { + return bridging::toJs(rt, "INVALID_PLACE_ID"); + } else if (value == NativeNavModuleRouteStatusSpec::UNKNOWN) { + return bridging::toJs(rt, "UNKNOWN"); + } else { + throw jsi::JSError(rt, "No appropriate enum member found for enum value"); + } + } +}; + +#pragma mark - NativeNavModuleArrivalEventSpec + +template +struct NativeNavModuleArrivalEventSpec { + P0 waypoint; + P1 isFinalDestination; + bool operator==(const NativeNavModuleArrivalEventSpec &other) const { + return waypoint == other.waypoint && isFinalDestination == other.isFinalDestination; + } +}; + +template +struct NativeNavModuleArrivalEventSpecBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "waypoint"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "isFinalDestination"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::Object waypointToJs(jsi::Runtime &rt, decltype(types.waypoint) value) { + return bridging::toJs(rt, value); + } + + static bool isFinalDestinationToJs(jsi::Runtime &rt, decltype(types.isFinalDestination) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "waypoint", bridging::toJs(rt, value.waypoint, jsInvoker)); + if (value.isFinalDestination) { + result.setProperty(rt, "isFinalDestination", bridging::toJs(rt, value.isFinalDestination.value(), jsInvoker)); + } + return result; + } +}; + + + +#pragma mark - NativeNavModuleDisplayOptionsSpec + +template +struct NativeNavModuleDisplayOptionsSpec { + P0 showDestinationMarkers; + P1 showStopSigns; + P2 showTrafficLights; + bool operator==(const NativeNavModuleDisplayOptionsSpec &other) const { + return showDestinationMarkers == other.showDestinationMarkers && showStopSigns == other.showStopSigns && showTrafficLights == other.showTrafficLights; + } +}; + +template +struct NativeNavModuleDisplayOptionsSpecBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "showDestinationMarkers"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "showStopSigns"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "showTrafficLights"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static bool showDestinationMarkersToJs(jsi::Runtime &rt, decltype(types.showDestinationMarkers) value) { + return bridging::toJs(rt, value); + } + + static bool showStopSignsToJs(jsi::Runtime &rt, decltype(types.showStopSigns) value) { + return bridging::toJs(rt, value); + } + + static bool showTrafficLightsToJs(jsi::Runtime &rt, decltype(types.showTrafficLights) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + if (value.showDestinationMarkers) { + result.setProperty(rt, "showDestinationMarkers", bridging::toJs(rt, value.showDestinationMarkers.value(), jsInvoker)); + } + if (value.showStopSigns) { + result.setProperty(rt, "showStopSigns", bridging::toJs(rt, value.showStopSigns.value(), jsInvoker)); + } + if (value.showTrafficLights) { + result.setProperty(rt, "showTrafficLights", bridging::toJs(rt, value.showTrafficLights.value(), jsInvoker)); + } + return result; + } +}; + + + +#pragma mark - NativeNavModuleLatLngSpec + +template +struct NativeNavModuleLatLngSpec { + P0 lat; + P1 lng; + bool operator==(const NativeNavModuleLatLngSpec &other) const { + return lat == other.lat && lng == other.lng; + } +}; + +template +struct NativeNavModuleLatLngSpecBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "lat"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "lng"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static double latToJs(jsi::Runtime &rt, decltype(types.lat) value) { + return bridging::toJs(rt, value); + } + + static double lngToJs(jsi::Runtime &rt, decltype(types.lng) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "lat", bridging::toJs(rt, value.lat, jsInvoker)); + result.setProperty(rt, "lng", bridging::toJs(rt, value.lng, jsInvoker)); + return result; + } +}; + + + +#pragma mark - NativeNavModuleLocationSimulationOptionsSpec + +template +struct NativeNavModuleLocationSimulationOptionsSpec { + P0 speedMultiplier; + bool operator==(const NativeNavModuleLocationSimulationOptionsSpec &other) const { + return speedMultiplier == other.speedMultiplier; + } +}; + +template +struct NativeNavModuleLocationSimulationOptionsSpecBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "speedMultiplier"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static double speedMultiplierToJs(jsi::Runtime &rt, decltype(types.speedMultiplier) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "speedMultiplier", bridging::toJs(rt, value.speedMultiplier, jsInvoker)); + return result; + } +}; + + + +#pragma mark - NativeNavModuleLocationSpec + +template +struct NativeNavModuleLocationSpec { + P0 lat; + P1 lng; + P2 altitude; + P3 bearing; + P4 speed; + P5 accuracy; + P6 verticalAccuracy; + P7 provider; + P8 time; + bool operator==(const NativeNavModuleLocationSpec &other) const { + return lat == other.lat && lng == other.lng && altitude == other.altitude && bearing == other.bearing && speed == other.speed && accuracy == other.accuracy && verticalAccuracy == other.verticalAccuracy && provider == other.provider && time == other.time; + } +}; + +template +struct NativeNavModuleLocationSpecBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "lat"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "lng"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "altitude"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "bearing"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "speed"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "accuracy"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "verticalAccuracy"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "provider"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "time"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static double latToJs(jsi::Runtime &rt, decltype(types.lat) value) { + return bridging::toJs(rt, value); + } + + static double lngToJs(jsi::Runtime &rt, decltype(types.lng) value) { + return bridging::toJs(rt, value); + } + + static double altitudeToJs(jsi::Runtime &rt, decltype(types.altitude) value) { + return bridging::toJs(rt, value); + } + + static double bearingToJs(jsi::Runtime &rt, decltype(types.bearing) value) { + return bridging::toJs(rt, value); + } + + static double speedToJs(jsi::Runtime &rt, decltype(types.speed) value) { + return bridging::toJs(rt, value); + } + + static double accuracyToJs(jsi::Runtime &rt, decltype(types.accuracy) value) { + return bridging::toJs(rt, value); + } + + static double verticalAccuracyToJs(jsi::Runtime &rt, decltype(types.verticalAccuracy) value) { + return bridging::toJs(rt, value); + } + + static jsi::String providerToJs(jsi::Runtime &rt, decltype(types.provider) value) { + return bridging::toJs(rt, value); + } + + static double timeToJs(jsi::Runtime &rt, decltype(types.time) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "lat", bridging::toJs(rt, value.lat, jsInvoker)); + result.setProperty(rt, "lng", bridging::toJs(rt, value.lng, jsInvoker)); + if (value.altitude) { + result.setProperty(rt, "altitude", bridging::toJs(rt, value.altitude.value(), jsInvoker)); + } + if (value.bearing) { + result.setProperty(rt, "bearing", bridging::toJs(rt, value.bearing.value(), jsInvoker)); + } + result.setProperty(rt, "speed", bridging::toJs(rt, value.speed, jsInvoker)); + if (value.accuracy) { + result.setProperty(rt, "accuracy", bridging::toJs(rt, value.accuracy.value(), jsInvoker)); + } + if (value.verticalAccuracy) { + result.setProperty(rt, "verticalAccuracy", bridging::toJs(rt, value.verticalAccuracy.value(), jsInvoker)); + } + if (value.provider) { + result.setProperty(rt, "provider", bridging::toJs(rt, value.provider.value(), jsInvoker)); + } + result.setProperty(rt, "time", bridging::toJs(rt, value.time, jsInvoker)); + return result; + } +}; + + + +#pragma mark - NativeNavModuleRoutingOptionsSpec + +template +struct NativeNavModuleRoutingOptionsSpec { + P0 travelMode; + P1 routingStrategy; + P2 alternateRoutesStrategy; + P3 avoidFerries; + P4 avoidTolls; + P5 avoidHighways; + bool operator==(const NativeNavModuleRoutingOptionsSpec &other) const { + return travelMode == other.travelMode && routingStrategy == other.routingStrategy && alternateRoutesStrategy == other.alternateRoutesStrategy && avoidFerries == other.avoidFerries && avoidTolls == other.avoidTolls && avoidHighways == other.avoidHighways; + } +}; + +template +struct NativeNavModuleRoutingOptionsSpecBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "travelMode"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "routingStrategy"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "alternateRoutesStrategy"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "avoidFerries"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "avoidTolls"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "avoidHighways"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static double travelModeToJs(jsi::Runtime &rt, decltype(types.travelMode) value) { + return bridging::toJs(rt, value); + } + + static double routingStrategyToJs(jsi::Runtime &rt, decltype(types.routingStrategy) value) { + return bridging::toJs(rt, value); + } + + static double alternateRoutesStrategyToJs(jsi::Runtime &rt, decltype(types.alternateRoutesStrategy) value) { + return bridging::toJs(rt, value); + } + + static bool avoidFerriesToJs(jsi::Runtime &rt, decltype(types.avoidFerries) value) { + return bridging::toJs(rt, value); + } + + static bool avoidTollsToJs(jsi::Runtime &rt, decltype(types.avoidTolls) value) { + return bridging::toJs(rt, value); + } + + static bool avoidHighwaysToJs(jsi::Runtime &rt, decltype(types.avoidHighways) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + if (value.travelMode) { + result.setProperty(rt, "travelMode", bridging::toJs(rt, value.travelMode.value(), jsInvoker)); + } + if (value.routingStrategy) { + result.setProperty(rt, "routingStrategy", bridging::toJs(rt, value.routingStrategy.value(), jsInvoker)); + } + if (value.alternateRoutesStrategy) { + result.setProperty(rt, "alternateRoutesStrategy", bridging::toJs(rt, value.alternateRoutesStrategy.value(), jsInvoker)); + } + if (value.avoidFerries) { + result.setProperty(rt, "avoidFerries", bridging::toJs(rt, value.avoidFerries.value(), jsInvoker)); + } + if (value.avoidTolls) { + result.setProperty(rt, "avoidTolls", bridging::toJs(rt, value.avoidTolls.value(), jsInvoker)); + } + if (value.avoidHighways) { + result.setProperty(rt, "avoidHighways", bridging::toJs(rt, value.avoidHighways.value(), jsInvoker)); + } + return result; + } +}; + + + +#pragma mark - NativeNavModuleSpeedAlertOptionsSpec + +template +struct NativeNavModuleSpeedAlertOptionsSpec { + P0 majorSpeedAlertPercentThreshold; + P1 minorSpeedAlertPercentThreshold; + P2 severityUpgradeDurationSeconds; + bool operator==(const NativeNavModuleSpeedAlertOptionsSpec &other) const { + return majorSpeedAlertPercentThreshold == other.majorSpeedAlertPercentThreshold && minorSpeedAlertPercentThreshold == other.minorSpeedAlertPercentThreshold && severityUpgradeDurationSeconds == other.severityUpgradeDurationSeconds; + } +}; + +template +struct NativeNavModuleSpeedAlertOptionsSpecBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "majorSpeedAlertPercentThreshold"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "minorSpeedAlertPercentThreshold"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "severityUpgradeDurationSeconds"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static double majorSpeedAlertPercentThresholdToJs(jsi::Runtime &rt, decltype(types.majorSpeedAlertPercentThreshold) value) { + return bridging::toJs(rt, value); + } + + static double minorSpeedAlertPercentThresholdToJs(jsi::Runtime &rt, decltype(types.minorSpeedAlertPercentThreshold) value) { + return bridging::toJs(rt, value); + } + + static double severityUpgradeDurationSecondsToJs(jsi::Runtime &rt, decltype(types.severityUpgradeDurationSeconds) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "majorSpeedAlertPercentThreshold", bridging::toJs(rt, value.majorSpeedAlertPercentThreshold, jsInvoker)); + result.setProperty(rt, "minorSpeedAlertPercentThreshold", bridging::toJs(rt, value.minorSpeedAlertPercentThreshold, jsInvoker)); + result.setProperty(rt, "severityUpgradeDurationSeconds", bridging::toJs(rt, value.severityUpgradeDurationSeconds, jsInvoker)); + return result; + } +}; + + + +#pragma mark - NativeNavModuleStepInfoSpec + +template +struct NativeNavModuleStepInfoSpec { + P0 instruction; + P1 distanceMeters; + P2 durationSeconds; + P3 maneuver; + P4 position; + bool operator==(const NativeNavModuleStepInfoSpec &other) const { + return instruction == other.instruction && distanceMeters == other.distanceMeters && durationSeconds == other.durationSeconds && maneuver == other.maneuver && position == other.position; + } +}; + +template +struct NativeNavModuleStepInfoSpecBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "instruction"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "distanceMeters"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "durationSeconds"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "maneuver"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "position"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::String instructionToJs(jsi::Runtime &rt, decltype(types.instruction) value) { + return bridging::toJs(rt, value); + } + + static double distanceMetersToJs(jsi::Runtime &rt, decltype(types.distanceMeters) value) { + return bridging::toJs(rt, value); + } + + static double durationSecondsToJs(jsi::Runtime &rt, decltype(types.durationSeconds) value) { + return bridging::toJs(rt, value); + } + + static jsi::String maneuverToJs(jsi::Runtime &rt, decltype(types.maneuver) value) { + return bridging::toJs(rt, value); + } + + static jsi::Object positionToJs(jsi::Runtime &rt, decltype(types.position) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "instruction", bridging::toJs(rt, value.instruction, jsInvoker)); + result.setProperty(rt, "distanceMeters", bridging::toJs(rt, value.distanceMeters, jsInvoker)); + result.setProperty(rt, "durationSeconds", bridging::toJs(rt, value.durationSeconds, jsInvoker)); + result.setProperty(rt, "maneuver", bridging::toJs(rt, value.maneuver, jsInvoker)); + result.setProperty(rt, "position", bridging::toJs(rt, value.position, jsInvoker)); + return result; + } +}; + + + +#pragma mark - NativeNavModuleTOSDialogOptionsSpec + +template +struct NativeNavModuleTOSDialogOptionsSpec { + P0 title; + P1 companyName; + P2 showOnlyDisclaimer; + bool operator==(const NativeNavModuleTOSDialogOptionsSpec &other) const { + return title == other.title && companyName == other.companyName && showOnlyDisclaimer == other.showOnlyDisclaimer; + } +}; + +template +struct NativeNavModuleTOSDialogOptionsSpecBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "title"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "companyName"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "showOnlyDisclaimer"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::String titleToJs(jsi::Runtime &rt, decltype(types.title) value) { + return bridging::toJs(rt, value); + } + + static jsi::String companyNameToJs(jsi::Runtime &rt, decltype(types.companyName) value) { + return bridging::toJs(rt, value); + } + + static bool showOnlyDisclaimerToJs(jsi::Runtime &rt, decltype(types.showOnlyDisclaimer) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + if (value.title) { + result.setProperty(rt, "title", bridging::toJs(rt, value.title.value(), jsInvoker)); + } + if (value.companyName) { + result.setProperty(rt, "companyName", bridging::toJs(rt, value.companyName.value(), jsInvoker)); + } + if (value.showOnlyDisclaimer) { + result.setProperty(rt, "showOnlyDisclaimer", bridging::toJs(rt, value.showOnlyDisclaimer.value(), jsInvoker)); + } + return result; + } +}; + + + +#pragma mark - NativeNavModuleTurnByTurnEventSpec + +template +struct NativeNavModuleTurnByTurnEventSpec { + P0 navState; + P1 routeChanged; + P2 distanceToCurrentStepMeters; + P3 distanceToFinalDestinationMeters; + P4 timeToCurrentStepSeconds; + P5 distanceToNextDestinationMeters; + P6 timeToNextDestinationSeconds; + P7 timeToFinalDestinationSeconds; + P8 currentStep; + P9 getRemainingSteps; + bool operator==(const NativeNavModuleTurnByTurnEventSpec &other) const { + return navState == other.navState && routeChanged == other.routeChanged && distanceToCurrentStepMeters == other.distanceToCurrentStepMeters && distanceToFinalDestinationMeters == other.distanceToFinalDestinationMeters && timeToCurrentStepSeconds == other.timeToCurrentStepSeconds && distanceToNextDestinationMeters == other.distanceToNextDestinationMeters && timeToNextDestinationSeconds == other.timeToNextDestinationSeconds && timeToFinalDestinationSeconds == other.timeToFinalDestinationSeconds && currentStep == other.currentStep && getRemainingSteps == other.getRemainingSteps; + } +}; + +template +struct NativeNavModuleTurnByTurnEventSpecBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "navState"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "routeChanged"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "distanceToCurrentStepMeters"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "distanceToFinalDestinationMeters"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "timeToCurrentStepSeconds"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "distanceToNextDestinationMeters"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "timeToNextDestinationSeconds"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "timeToFinalDestinationSeconds"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "currentStep"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "getRemainingSteps"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static double navStateToJs(jsi::Runtime &rt, decltype(types.navState) value) { + return bridging::toJs(rt, value); + } + + static bool routeChangedToJs(jsi::Runtime &rt, decltype(types.routeChanged) value) { + return bridging::toJs(rt, value); + } + + static double distanceToCurrentStepMetersToJs(jsi::Runtime &rt, decltype(types.distanceToCurrentStepMeters) value) { + return bridging::toJs(rt, value); + } + + static double distanceToFinalDestinationMetersToJs(jsi::Runtime &rt, decltype(types.distanceToFinalDestinationMeters) value) { + return bridging::toJs(rt, value); + } + + static double timeToCurrentStepSecondsToJs(jsi::Runtime &rt, decltype(types.timeToCurrentStepSeconds) value) { + return bridging::toJs(rt, value); + } + + static double distanceToNextDestinationMetersToJs(jsi::Runtime &rt, decltype(types.distanceToNextDestinationMeters) value) { + return bridging::toJs(rt, value); + } + + static double timeToNextDestinationSecondsToJs(jsi::Runtime &rt, decltype(types.timeToNextDestinationSeconds) value) { + return bridging::toJs(rt, value); + } + + static double timeToFinalDestinationSecondsToJs(jsi::Runtime &rt, decltype(types.timeToFinalDestinationSeconds) value) { + return bridging::toJs(rt, value); + } + + static jsi::Object currentStepToJs(jsi::Runtime &rt, decltype(types.currentStep) value) { + return bridging::toJs(rt, value); + } + + static jsi::Array getRemainingStepsToJs(jsi::Runtime &rt, decltype(types.getRemainingSteps) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "navState", bridging::toJs(rt, value.navState, jsInvoker)); + result.setProperty(rt, "routeChanged", bridging::toJs(rt, value.routeChanged, jsInvoker)); + if (value.distanceToCurrentStepMeters) { + result.setProperty(rt, "distanceToCurrentStepMeters", bridging::toJs(rt, value.distanceToCurrentStepMeters.value(), jsInvoker)); + } + if (value.distanceToFinalDestinationMeters) { + result.setProperty(rt, "distanceToFinalDestinationMeters", bridging::toJs(rt, value.distanceToFinalDestinationMeters.value(), jsInvoker)); + } + if (value.timeToCurrentStepSeconds) { + result.setProperty(rt, "timeToCurrentStepSeconds", bridging::toJs(rt, value.timeToCurrentStepSeconds.value(), jsInvoker)); + } + if (value.distanceToNextDestinationMeters) { + result.setProperty(rt, "distanceToNextDestinationMeters", bridging::toJs(rt, value.distanceToNextDestinationMeters.value(), jsInvoker)); + } + if (value.timeToNextDestinationSeconds) { + result.setProperty(rt, "timeToNextDestinationSeconds", bridging::toJs(rt, value.timeToNextDestinationSeconds.value(), jsInvoker)); + } + if (value.timeToFinalDestinationSeconds) { + result.setProperty(rt, "timeToFinalDestinationSeconds", bridging::toJs(rt, value.timeToFinalDestinationSeconds.value(), jsInvoker)); + } + if (value.currentStep) { + result.setProperty(rt, "currentStep", bridging::toJs(rt, value.currentStep.value(), jsInvoker)); + } + result.setProperty(rt, "getRemainingSteps", bridging::toJs(rt, value.getRemainingSteps, jsInvoker)); + return result; + } +}; + + + +#pragma mark - NativeNavModuleWaypointSpec + +template +struct NativeNavModuleWaypointSpec { + P0 placeId; + P1 title; + P2 vehicleStopover; + P3 preferSameSideOfRoad; + P4 position; + P5 preferredHeading; + bool operator==(const NativeNavModuleWaypointSpec &other) const { + return placeId == other.placeId && title == other.title && vehicleStopover == other.vehicleStopover && preferSameSideOfRoad == other.preferSameSideOfRoad && position == other.position && preferredHeading == other.preferredHeading; + } +}; + +template +struct NativeNavModuleWaypointSpecBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "placeId"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "title"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "vehicleStopover"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "preferSameSideOfRoad"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "position"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "preferredHeading"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::String placeIdToJs(jsi::Runtime &rt, decltype(types.placeId) value) { + return bridging::toJs(rt, value); + } + + static jsi::String titleToJs(jsi::Runtime &rt, decltype(types.title) value) { + return bridging::toJs(rt, value); + } + + static bool vehicleStopoverToJs(jsi::Runtime &rt, decltype(types.vehicleStopover) value) { + return bridging::toJs(rt, value); + } + + static bool preferSameSideOfRoadToJs(jsi::Runtime &rt, decltype(types.preferSameSideOfRoad) value) { + return bridging::toJs(rt, value); + } + + static jsi::Object positionToJs(jsi::Runtime &rt, decltype(types.position) value) { + return bridging::toJs(rt, value); + } + + static double preferredHeadingToJs(jsi::Runtime &rt, decltype(types.preferredHeading) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + if (value.placeId) { + result.setProperty(rt, "placeId", bridging::toJs(rt, value.placeId.value(), jsInvoker)); + } + if (value.title) { + result.setProperty(rt, "title", bridging::toJs(rt, value.title.value(), jsInvoker)); + } + if (value.vehicleStopover) { + result.setProperty(rt, "vehicleStopover", bridging::toJs(rt, value.vehicleStopover.value(), jsInvoker)); + } + if (value.preferSameSideOfRoad) { + result.setProperty(rt, "preferSameSideOfRoad", bridging::toJs(rt, value.preferSameSideOfRoad.value(), jsInvoker)); + } + if (value.position) { + result.setProperty(rt, "position", bridging::toJs(rt, value.position.value(), jsInvoker)); + } + if (value.preferredHeading) { + result.setProperty(rt, "preferredHeading", bridging::toJs(rt, value.preferredHeading.value(), jsInvoker)); + } + return result; + } +}; + +class JSI_EXPORT NativeNavModuleCxxSpecJSI : public TurboModule { +protected: + NativeNavModuleCxxSpecJSI(std::shared_ptr jsInvoker); + +public: + virtual jsi::Value initializeNavigator(jsi::Runtime &rt, jsi::Object termsAndConditionsDialogOptions, double taskRemovedBehavior) = 0; + virtual jsi::Value cleanup(jsi::Runtime &rt) = 0; + virtual jsi::Value setDestinations(jsi::Runtime &rt, jsi::Array waypoints, std::optional routingOptions, std::optional displayOptions) = 0; + virtual jsi::Value continueToNextDestination(jsi::Runtime &rt) = 0; + virtual jsi::Value clearDestinations(jsi::Runtime &rt) = 0; + virtual jsi::Value startGuidance(jsi::Runtime &rt) = 0; + virtual jsi::Value stopGuidance(jsi::Runtime &rt) = 0; + virtual jsi::Value setSpeedAlertOptions(jsi::Runtime &rt, std::optional alertOptions) = 0; + virtual void setAbnormalTerminatingReportingEnabled(jsi::Runtime &rt, bool enabled) = 0; + virtual jsi::Value setAudioGuidanceType(jsi::Runtime &rt, double index) = 0; + virtual void setBackgroundLocationUpdatesEnabled(jsi::Runtime &rt, bool isEnabled) = 0; + virtual void setTurnByTurnLoggingEnabled(jsi::Runtime &rt, bool isEnabled) = 0; + virtual jsi::Value areTermsAccepted(jsi::Runtime &rt) = 0; + virtual jsi::Value getCurrentRouteSegment(jsi::Runtime &rt) = 0; + virtual jsi::Value getRouteSegments(jsi::Runtime &rt) = 0; + virtual jsi::Value getCurrentTimeAndDistance(jsi::Runtime &rt) = 0; + virtual jsi::Value getTraveledPath(jsi::Runtime &rt) = 0; + virtual jsi::Value getNavSDKVersion(jsi::Runtime &rt) = 0; + virtual jsi::Value stopUpdatingLocation(jsi::Runtime &rt) = 0; + virtual jsi::Value startUpdatingLocation(jsi::Runtime &rt) = 0; + virtual jsi::Value simulateLocation(jsi::Runtime &rt, jsi::Object location) = 0; + virtual jsi::Value resumeLocationSimulation(jsi::Runtime &rt) = 0; + virtual jsi::Value pauseLocationSimulation(jsi::Runtime &rt) = 0; + virtual jsi::Value simulateLocationsAlongExistingRoute(jsi::Runtime &rt, jsi::Object options) = 0; + virtual jsi::Value stopLocationSimulation(jsi::Runtime &rt) = 0; + virtual void resetTermsAccepted(jsi::Runtime &rt) = 0; + +}; + +template +class JSI_EXPORT NativeNavModuleCxxSpec : public TurboModule { +public: + jsi::Value create(jsi::Runtime &rt, const jsi::PropNameID &propName) override { + return delegate_.create(rt, propName); + } + + std::vector getPropertyNames(jsi::Runtime& runtime) override { + return delegate_.getPropertyNames(runtime); + } + + static constexpr std::string_view kModuleName = "NavModule"; + +protected: + NativeNavModuleCxxSpec(std::shared_ptr jsInvoker) + : TurboModule(std::string{NativeNavModuleCxxSpec::kModuleName}, jsInvoker), + delegate_(reinterpret_cast(this), jsInvoker) {} + + void emitOnNavigationReady() { + static_cast&>(*delegate_.eventEmitterMap_["onNavigationReady"]).emit(); + } + + template void emitOnLocationChanged(OnLocationChangedType value) { + static_assert(bridging::supportsFromJs, "value cannnot be converted to jsi::Object"); + static_cast&>(*delegate_.eventEmitterMap_["onLocationChanged"]).emit([jsInvoker = jsInvoker_, eventValue = value](jsi::Runtime& rt) -> jsi::Value { + return bridging::toJs(rt, eventValue, jsInvoker); + }); + } + + template void emitOnArrival(OnArrivalType value) { + static_assert(bridging::supportsFromJs, "value cannnot be converted to jsi::Object"); + static_cast&>(*delegate_.eventEmitterMap_["onArrival"]).emit([jsInvoker = jsInvoker_, eventValue = value](jsi::Runtime& rt) -> jsi::Value { + return bridging::toJs(rt, eventValue, jsInvoker); + }); + } + + void emitOnRemainingTimeOrDistanceChanged() { + static_cast&>(*delegate_.eventEmitterMap_["onRemainingTimeOrDistanceChanged"]).emit(); + } + + void emitOnRouteChanged() { + static_cast&>(*delegate_.eventEmitterMap_["onRouteChanged"]).emit(); + } + + void emitOnReroutingRequestedByOffRoute() { + static_cast&>(*delegate_.eventEmitterMap_["onReroutingRequestedByOffRoute"]).emit(); + } + + void emitOnStartGuidance() { + static_cast&>(*delegate_.eventEmitterMap_["onStartGuidance"]).emit(); + } + + template void emitOnTurnByTurn(OnTurnByTurnType value) { + static_assert(bridging::supportsFromJs, "value cannnot be converted to jsi::Object"); + static_cast&>(*delegate_.eventEmitterMap_["onTurnByTurn"]).emit([jsInvoker = jsInvoker_, eventValue = value](jsi::Runtime& rt) -> jsi::Value { + return bridging::toJs(rt, eventValue, jsInvoker); + }); + } + + template void emitOnRawLocationChanged(OnRawLocationChangedType value) { + static_assert(bridging::supportsFromJs, "value cannnot be converted to jsi::Object"); + static_cast&>(*delegate_.eventEmitterMap_["onRawLocationChanged"]).emit([jsInvoker = jsInvoker_, eventValue = value](jsi::Runtime& rt) -> jsi::Value { + return bridging::toJs(rt, eventValue, jsInvoker); + }); + } + + void emitOnTrafficUpdated() { + static_cast&>(*delegate_.eventEmitterMap_["onTrafficUpdated"]).emit(); + } + + template void emitLogDebugInfo(LogDebugInfoType value) { + static_assert(bridging::supportsFromJs, "value cannnot be converted to jsi::Object"); + static_cast&>(*delegate_.eventEmitterMap_["logDebugInfo"]).emit([jsInvoker = jsInvoker_, eventValue = value](jsi::Runtime& rt) -> jsi::Value { + return bridging::toJs(rt, eventValue, jsInvoker); + }); + } + +private: + class Delegate : public NativeNavModuleCxxSpecJSI { + public: + Delegate(T *instance, std::shared_ptr jsInvoker) : + NativeNavModuleCxxSpecJSI(std::move(jsInvoker)), instance_(instance) { + eventEmitterMap_["onNavigationReady"] = std::make_shared>(); + eventEmitterMap_["onLocationChanged"] = std::make_shared>(); + eventEmitterMap_["onArrival"] = std::make_shared>(); + eventEmitterMap_["onRemainingTimeOrDistanceChanged"] = std::make_shared>(); + eventEmitterMap_["onRouteChanged"] = std::make_shared>(); + eventEmitterMap_["onReroutingRequestedByOffRoute"] = std::make_shared>(); + eventEmitterMap_["onStartGuidance"] = std::make_shared>(); + eventEmitterMap_["onTurnByTurn"] = std::make_shared>(); + eventEmitterMap_["onRawLocationChanged"] = std::make_shared>(); + eventEmitterMap_["onTrafficUpdated"] = std::make_shared>(); + eventEmitterMap_["logDebugInfo"] = std::make_shared>(); + } + + jsi::Value initializeNavigator(jsi::Runtime &rt, jsi::Object termsAndConditionsDialogOptions, double taskRemovedBehavior) override { + static_assert( + bridging::getParameterCount(&T::initializeNavigator) == 3, + "Expected initializeNavigator(...) to have 3 parameters"); + + return bridging::callFromJs( + rt, &T::initializeNavigator, jsInvoker_, instance_, std::move(termsAndConditionsDialogOptions), std::move(taskRemovedBehavior)); + } + jsi::Value cleanup(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::cleanup) == 1, + "Expected cleanup(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::cleanup, jsInvoker_, instance_); + } + jsi::Value setDestinations(jsi::Runtime &rt, jsi::Array waypoints, std::optional routingOptions, std::optional displayOptions) override { + static_assert( + bridging::getParameterCount(&T::setDestinations) == 4, + "Expected setDestinations(...) to have 4 parameters"); + + return bridging::callFromJs( + rt, &T::setDestinations, jsInvoker_, instance_, std::move(waypoints), std::move(routingOptions), std::move(displayOptions)); + } + jsi::Value continueToNextDestination(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::continueToNextDestination) == 1, + "Expected continueToNextDestination(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::continueToNextDestination, jsInvoker_, instance_); + } + jsi::Value clearDestinations(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::clearDestinations) == 1, + "Expected clearDestinations(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::clearDestinations, jsInvoker_, instance_); + } + jsi::Value startGuidance(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::startGuidance) == 1, + "Expected startGuidance(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::startGuidance, jsInvoker_, instance_); + } + jsi::Value stopGuidance(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::stopGuidance) == 1, + "Expected stopGuidance(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::stopGuidance, jsInvoker_, instance_); + } + jsi::Value setSpeedAlertOptions(jsi::Runtime &rt, std::optional alertOptions) override { + static_assert( + bridging::getParameterCount(&T::setSpeedAlertOptions) == 2, + "Expected setSpeedAlertOptions(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::setSpeedAlertOptions, jsInvoker_, instance_, std::move(alertOptions)); + } + void setAbnormalTerminatingReportingEnabled(jsi::Runtime &rt, bool enabled) override { + static_assert( + bridging::getParameterCount(&T::setAbnormalTerminatingReportingEnabled) == 2, + "Expected setAbnormalTerminatingReportingEnabled(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::setAbnormalTerminatingReportingEnabled, jsInvoker_, instance_, std::move(enabled)); + } + jsi::Value setAudioGuidanceType(jsi::Runtime &rt, double index) override { + static_assert( + bridging::getParameterCount(&T::setAudioGuidanceType) == 2, + "Expected setAudioGuidanceType(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::setAudioGuidanceType, jsInvoker_, instance_, std::move(index)); + } + void setBackgroundLocationUpdatesEnabled(jsi::Runtime &rt, bool isEnabled) override { + static_assert( + bridging::getParameterCount(&T::setBackgroundLocationUpdatesEnabled) == 2, + "Expected setBackgroundLocationUpdatesEnabled(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::setBackgroundLocationUpdatesEnabled, jsInvoker_, instance_, std::move(isEnabled)); + } + void setTurnByTurnLoggingEnabled(jsi::Runtime &rt, bool isEnabled) override { + static_assert( + bridging::getParameterCount(&T::setTurnByTurnLoggingEnabled) == 2, + "Expected setTurnByTurnLoggingEnabled(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::setTurnByTurnLoggingEnabled, jsInvoker_, instance_, std::move(isEnabled)); + } + jsi::Value areTermsAccepted(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::areTermsAccepted) == 1, + "Expected areTermsAccepted(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::areTermsAccepted, jsInvoker_, instance_); + } + jsi::Value getCurrentRouteSegment(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::getCurrentRouteSegment) == 1, + "Expected getCurrentRouteSegment(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::getCurrentRouteSegment, jsInvoker_, instance_); + } + jsi::Value getRouteSegments(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::getRouteSegments) == 1, + "Expected getRouteSegments(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::getRouteSegments, jsInvoker_, instance_); + } + jsi::Value getCurrentTimeAndDistance(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::getCurrentTimeAndDistance) == 1, + "Expected getCurrentTimeAndDistance(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::getCurrentTimeAndDistance, jsInvoker_, instance_); + } + jsi::Value getTraveledPath(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::getTraveledPath) == 1, + "Expected getTraveledPath(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::getTraveledPath, jsInvoker_, instance_); + } + jsi::Value getNavSDKVersion(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::getNavSDKVersion) == 1, + "Expected getNavSDKVersion(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::getNavSDKVersion, jsInvoker_, instance_); + } + jsi::Value stopUpdatingLocation(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::stopUpdatingLocation) == 1, + "Expected stopUpdatingLocation(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::stopUpdatingLocation, jsInvoker_, instance_); + } + jsi::Value startUpdatingLocation(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::startUpdatingLocation) == 1, + "Expected startUpdatingLocation(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::startUpdatingLocation, jsInvoker_, instance_); + } + jsi::Value simulateLocation(jsi::Runtime &rt, jsi::Object location) override { + static_assert( + bridging::getParameterCount(&T::simulateLocation) == 2, + "Expected simulateLocation(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::simulateLocation, jsInvoker_, instance_, std::move(location)); + } + jsi::Value resumeLocationSimulation(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::resumeLocationSimulation) == 1, + "Expected resumeLocationSimulation(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::resumeLocationSimulation, jsInvoker_, instance_); + } + jsi::Value pauseLocationSimulation(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::pauseLocationSimulation) == 1, + "Expected pauseLocationSimulation(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::pauseLocationSimulation, jsInvoker_, instance_); + } + jsi::Value simulateLocationsAlongExistingRoute(jsi::Runtime &rt, jsi::Object options) override { + static_assert( + bridging::getParameterCount(&T::simulateLocationsAlongExistingRoute) == 2, + "Expected simulateLocationsAlongExistingRoute(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::simulateLocationsAlongExistingRoute, jsInvoker_, instance_, std::move(options)); + } + jsi::Value stopLocationSimulation(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::stopLocationSimulation) == 1, + "Expected stopLocationSimulation(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::stopLocationSimulation, jsInvoker_, instance_); + } + void resetTermsAccepted(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::resetTermsAccepted) == 1, + "Expected resetTermsAccepted(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::resetTermsAccepted, jsInvoker_, instance_); + } + + private: + friend class NativeNavModuleCxxSpec; + T *instance_; + }; + + Delegate delegate_; +}; + + + +#pragma mark - NativeNavViewModuleCameraPositionSpec + +template +struct NativeNavViewModuleCameraPositionSpec { + P0 target; + P1 bearing; + P2 tilt; + P3 zoom; + bool operator==(const NativeNavViewModuleCameraPositionSpec &other) const { + return target == other.target && bearing == other.bearing && tilt == other.tilt && zoom == other.zoom; + } +}; + +template +struct NativeNavViewModuleCameraPositionSpecBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "target"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "bearing"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "tilt"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "zoom"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static std::optional targetToJs(jsi::Runtime &rt, decltype(types.target) value) { + return bridging::toJs(rt, value); + } + + static std::optional bearingToJs(jsi::Runtime &rt, decltype(types.bearing) value) { + return bridging::toJs(rt, value); + } + + static std::optional tiltToJs(jsi::Runtime &rt, decltype(types.tilt) value) { + return bridging::toJs(rt, value); + } + + static std::optional zoomToJs(jsi::Runtime &rt, decltype(types.zoom) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + if (value.target) { + result.setProperty(rt, "target", bridging::toJs(rt, value.target.value(), jsInvoker)); + } + if (value.bearing) { + result.setProperty(rt, "bearing", bridging::toJs(rt, value.bearing.value(), jsInvoker)); + } + if (value.tilt) { + result.setProperty(rt, "tilt", bridging::toJs(rt, value.tilt.value(), jsInvoker)); + } + if (value.zoom) { + result.setProperty(rt, "zoom", bridging::toJs(rt, value.zoom.value(), jsInvoker)); + } + return result; + } +}; + + + +#pragma mark - NativeNavViewModuleCircleOptionsSpec + +template +struct NativeNavViewModuleCircleOptionsSpec { + P0 center; + P1 id; + P2 radius; + P3 strokeWidth; + P4 strokeColor; + P5 fillColor; + P6 clickable; + P7 visible; + P8 zIndex; + bool operator==(const NativeNavViewModuleCircleOptionsSpec &other) const { + return center == other.center && id == other.id && radius == other.radius && strokeWidth == other.strokeWidth && strokeColor == other.strokeColor && fillColor == other.fillColor && clickable == other.clickable && visible == other.visible && zIndex == other.zIndex; + } +}; + +template +struct NativeNavViewModuleCircleOptionsSpecBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "center"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "id"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "radius"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "strokeWidth"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "strokeColor"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "fillColor"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "clickable"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "visible"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "zIndex"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::Object centerToJs(jsi::Runtime &rt, decltype(types.center) value) { + return bridging::toJs(rt, value); + } + + static std::optional idToJs(jsi::Runtime &rt, decltype(types.id) value) { + return bridging::toJs(rt, value); + } + + static double radiusToJs(jsi::Runtime &rt, decltype(types.radius) value) { + return bridging::toJs(rt, value); + } + + static std::optional strokeWidthToJs(jsi::Runtime &rt, decltype(types.strokeWidth) value) { + return bridging::toJs(rt, value); + } + + static std::optional strokeColorToJs(jsi::Runtime &rt, decltype(types.strokeColor) value) { + return bridging::toJs(rt, value); + } + + static std::optional fillColorToJs(jsi::Runtime &rt, decltype(types.fillColor) value) { + return bridging::toJs(rt, value); + } + + static std::optional clickableToJs(jsi::Runtime &rt, decltype(types.clickable) value) { + return bridging::toJs(rt, value); + } + + static std::optional visibleToJs(jsi::Runtime &rt, decltype(types.visible) value) { + return bridging::toJs(rt, value); + } + + static std::optional zIndexToJs(jsi::Runtime &rt, decltype(types.zIndex) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "center", bridging::toJs(rt, value.center, jsInvoker)); + if (value.id) { + result.setProperty(rt, "id", bridging::toJs(rt, value.id.value(), jsInvoker)); + } + result.setProperty(rt, "radius", bridging::toJs(rt, value.radius, jsInvoker)); + if (value.strokeWidth) { + result.setProperty(rt, "strokeWidth", bridging::toJs(rt, value.strokeWidth.value(), jsInvoker)); + } + if (value.strokeColor) { + result.setProperty(rt, "strokeColor", bridging::toJs(rt, value.strokeColor.value(), jsInvoker)); + } + if (value.fillColor) { + result.setProperty(rt, "fillColor", bridging::toJs(rt, value.fillColor.value(), jsInvoker)); + } + if (value.clickable) { + result.setProperty(rt, "clickable", bridging::toJs(rt, value.clickable.value(), jsInvoker)); + } + if (value.visible) { + result.setProperty(rt, "visible", bridging::toJs(rt, value.visible.value(), jsInvoker)); + } + if (value.zIndex) { + result.setProperty(rt, "zIndex", bridging::toJs(rt, value.zIndex.value(), jsInvoker)); + } + return result; + } +}; + + + +#pragma mark - NativeNavViewModuleMarkerOptionsSpec + +template +struct NativeNavViewModuleMarkerOptionsSpec { + P0 position; + P1 id; + P2 imgPath; + P3 title; + P4 snippet; + P5 alpha; + P6 rotation; + P7 draggable; + P8 flat; + P9 visible; + P10 zIndex; + bool operator==(const NativeNavViewModuleMarkerOptionsSpec &other) const { + return position == other.position && id == other.id && imgPath == other.imgPath && title == other.title && snippet == other.snippet && alpha == other.alpha && rotation == other.rotation && draggable == other.draggable && flat == other.flat && visible == other.visible && zIndex == other.zIndex; + } +}; + +template +struct NativeNavViewModuleMarkerOptionsSpecBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "position"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "id"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "imgPath"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "title"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "snippet"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "alpha"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "rotation"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "draggable"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "flat"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "visible"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "zIndex"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::Object positionToJs(jsi::Runtime &rt, decltype(types.position) value) { + return bridging::toJs(rt, value); + } + + static std::optional idToJs(jsi::Runtime &rt, decltype(types.id) value) { + return bridging::toJs(rt, value); + } + + static std::optional imgPathToJs(jsi::Runtime &rt, decltype(types.imgPath) value) { + return bridging::toJs(rt, value); + } + + static std::optional titleToJs(jsi::Runtime &rt, decltype(types.title) value) { + return bridging::toJs(rt, value); + } + + static std::optional snippetToJs(jsi::Runtime &rt, decltype(types.snippet) value) { + return bridging::toJs(rt, value); + } + + static std::optional alphaToJs(jsi::Runtime &rt, decltype(types.alpha) value) { + return bridging::toJs(rt, value); + } + + static std::optional rotationToJs(jsi::Runtime &rt, decltype(types.rotation) value) { + return bridging::toJs(rt, value); + } + + static std::optional draggableToJs(jsi::Runtime &rt, decltype(types.draggable) value) { + return bridging::toJs(rt, value); + } + + static std::optional flatToJs(jsi::Runtime &rt, decltype(types.flat) value) { + return bridging::toJs(rt, value); + } + + static std::optional visibleToJs(jsi::Runtime &rt, decltype(types.visible) value) { + return bridging::toJs(rt, value); + } + + static std::optional zIndexToJs(jsi::Runtime &rt, decltype(types.zIndex) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "position", bridging::toJs(rt, value.position, jsInvoker)); + if (value.id) { + result.setProperty(rt, "id", bridging::toJs(rt, value.id.value(), jsInvoker)); + } + if (value.imgPath) { + result.setProperty(rt, "imgPath", bridging::toJs(rt, value.imgPath.value(), jsInvoker)); + } + if (value.title) { + result.setProperty(rt, "title", bridging::toJs(rt, value.title.value(), jsInvoker)); + } + if (value.snippet) { + result.setProperty(rt, "snippet", bridging::toJs(rt, value.snippet.value(), jsInvoker)); + } + if (value.alpha) { + result.setProperty(rt, "alpha", bridging::toJs(rt, value.alpha.value(), jsInvoker)); + } + if (value.rotation) { + result.setProperty(rt, "rotation", bridging::toJs(rt, value.rotation.value(), jsInvoker)); + } + if (value.draggable) { + result.setProperty(rt, "draggable", bridging::toJs(rt, value.draggable.value(), jsInvoker)); + } + if (value.flat) { + result.setProperty(rt, "flat", bridging::toJs(rt, value.flat.value(), jsInvoker)); + } + if (value.visible) { + result.setProperty(rt, "visible", bridging::toJs(rt, value.visible.value(), jsInvoker)); + } + if (value.zIndex) { + result.setProperty(rt, "zIndex", bridging::toJs(rt, value.zIndex.value(), jsInvoker)); + } + return result; + } +}; + + + +#pragma mark - NativeNavViewModulePolygonOptionsSpec + +template +struct NativeNavViewModulePolygonOptionsSpec { + P0 points; + P1 id; + P2 holes; + P3 strokeWidth; + P4 strokeColor; + P5 fillColor; + P6 geodesic; + P7 clickable; + P8 visible; + P9 zIndex; + bool operator==(const NativeNavViewModulePolygonOptionsSpec &other) const { + return points == other.points && id == other.id && holes == other.holes && strokeWidth == other.strokeWidth && strokeColor == other.strokeColor && fillColor == other.fillColor && geodesic == other.geodesic && clickable == other.clickable && visible == other.visible && zIndex == other.zIndex; + } +}; + +template +struct NativeNavViewModulePolygonOptionsSpecBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "points"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "id"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "holes"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "strokeWidth"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "strokeColor"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "fillColor"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "geodesic"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "clickable"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "visible"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "zIndex"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::Array pointsToJs(jsi::Runtime &rt, decltype(types.points) value) { + return bridging::toJs(rt, value); + } + + static std::optional idToJs(jsi::Runtime &rt, decltype(types.id) value) { + return bridging::toJs(rt, value); + } + + static jsi::Array holesToJs(jsi::Runtime &rt, decltype(types.holes) value) { + return bridging::toJs(rt, value); + } + + static std::optional strokeWidthToJs(jsi::Runtime &rt, decltype(types.strokeWidth) value) { + return bridging::toJs(rt, value); + } + + static std::optional strokeColorToJs(jsi::Runtime &rt, decltype(types.strokeColor) value) { + return bridging::toJs(rt, value); + } + + static std::optional fillColorToJs(jsi::Runtime &rt, decltype(types.fillColor) value) { + return bridging::toJs(rt, value); + } + + static std::optional geodesicToJs(jsi::Runtime &rt, decltype(types.geodesic) value) { + return bridging::toJs(rt, value); + } + + static std::optional clickableToJs(jsi::Runtime &rt, decltype(types.clickable) value) { + return bridging::toJs(rt, value); + } + + static std::optional visibleToJs(jsi::Runtime &rt, decltype(types.visible) value) { + return bridging::toJs(rt, value); + } + + static std::optional zIndexToJs(jsi::Runtime &rt, decltype(types.zIndex) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "points", bridging::toJs(rt, value.points, jsInvoker)); + if (value.id) { + result.setProperty(rt, "id", bridging::toJs(rt, value.id.value(), jsInvoker)); + } + result.setProperty(rt, "holes", bridging::toJs(rt, value.holes, jsInvoker)); + if (value.strokeWidth) { + result.setProperty(rt, "strokeWidth", bridging::toJs(rt, value.strokeWidth.value(), jsInvoker)); + } + if (value.strokeColor) { + result.setProperty(rt, "strokeColor", bridging::toJs(rt, value.strokeColor.value(), jsInvoker)); + } + if (value.fillColor) { + result.setProperty(rt, "fillColor", bridging::toJs(rt, value.fillColor.value(), jsInvoker)); + } + if (value.geodesic) { + result.setProperty(rt, "geodesic", bridging::toJs(rt, value.geodesic.value(), jsInvoker)); + } + if (value.clickable) { + result.setProperty(rt, "clickable", bridging::toJs(rt, value.clickable.value(), jsInvoker)); + } + if (value.visible) { + result.setProperty(rt, "visible", bridging::toJs(rt, value.visible.value(), jsInvoker)); + } + if (value.zIndex) { + result.setProperty(rt, "zIndex", bridging::toJs(rt, value.zIndex.value(), jsInvoker)); + } + return result; + } +}; + + + +#pragma mark - NativeNavViewModulePolylineOptionsSpec + +template +struct NativeNavViewModulePolylineOptionsSpec { + P0 points; + P1 id; + P2 color; + P3 width; + P4 clickable; + P5 visible; + P6 zIndex; + bool operator==(const NativeNavViewModulePolylineOptionsSpec &other) const { + return points == other.points && id == other.id && color == other.color && width == other.width && clickable == other.clickable && visible == other.visible && zIndex == other.zIndex; + } +}; + +template +struct NativeNavViewModulePolylineOptionsSpecBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "points"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "id"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "color"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "width"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "clickable"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "visible"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "zIndex"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::Array pointsToJs(jsi::Runtime &rt, decltype(types.points) value) { + return bridging::toJs(rt, value); + } + + static std::optional idToJs(jsi::Runtime &rt, decltype(types.id) value) { + return bridging::toJs(rt, value); + } + + static std::optional colorToJs(jsi::Runtime &rt, decltype(types.color) value) { + return bridging::toJs(rt, value); + } + + static std::optional widthToJs(jsi::Runtime &rt, decltype(types.width) value) { + return bridging::toJs(rt, value); + } + + static std::optional clickableToJs(jsi::Runtime &rt, decltype(types.clickable) value) { + return bridging::toJs(rt, value); + } + + static std::optional visibleToJs(jsi::Runtime &rt, decltype(types.visible) value) { + return bridging::toJs(rt, value); + } + + static std::optional zIndexToJs(jsi::Runtime &rt, decltype(types.zIndex) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "points", bridging::toJs(rt, value.points, jsInvoker)); + if (value.id) { + result.setProperty(rt, "id", bridging::toJs(rt, value.id.value(), jsInvoker)); + } + if (value.color) { + result.setProperty(rt, "color", bridging::toJs(rt, value.color.value(), jsInvoker)); + } + if (value.width) { + result.setProperty(rt, "width", bridging::toJs(rt, value.width.value(), jsInvoker)); + } + if (value.clickable) { + result.setProperty(rt, "clickable", bridging::toJs(rt, value.clickable.value(), jsInvoker)); + } + if (value.visible) { + result.setProperty(rt, "visible", bridging::toJs(rt, value.visible.value(), jsInvoker)); + } + if (value.zIndex) { + result.setProperty(rt, "zIndex", bridging::toJs(rt, value.zIndex.value(), jsInvoker)); + } + return result; + } +}; + +class JSI_EXPORT NativeNavViewModuleCxxSpecJSI : public TurboModule { +protected: + NativeNavViewModuleCxxSpecJSI(std::shared_ptr jsInvoker); + +public: + virtual jsi::Value addCircle(jsi::Runtime &rt, double viewId, jsi::Object options) = 0; + virtual jsi::Value addMarker(jsi::Runtime &rt, double viewId, jsi::Object options) = 0; + virtual jsi::Value addPolyline(jsi::Runtime &rt, double viewId, jsi::Object options) = 0; + virtual jsi::Value addPolygon(jsi::Runtime &rt, double viewId, jsi::Object options) = 0; + virtual jsi::Value addGroundOverlay(jsi::Runtime &rt, double viewId, jsi::Object options) = 0; + virtual jsi::Value moveCamera(jsi::Runtime &rt, double viewId, jsi::Object cameraPosition) = 0; + virtual jsi::Value getCameraPosition(jsi::Runtime &rt, double viewId) = 0; + virtual jsi::Value getMyLocation(jsi::Runtime &rt, double viewId) = 0; + virtual jsi::Value getUiSettings(jsi::Runtime &rt, double viewId) = 0; + virtual jsi::Value isMyLocationEnabled(jsi::Runtime &rt, double viewId) = 0; + virtual jsi::Value showRouteOverview(jsi::Runtime &rt, double viewId) = 0; + virtual jsi::Value clearMapView(jsi::Runtime &rt, double viewId) = 0; + virtual jsi::Value removeMarker(jsi::Runtime &rt, double viewId, jsi::String id) = 0; + virtual jsi::Value removePolyline(jsi::Runtime &rt, double viewId, jsi::String id) = 0; + virtual jsi::Value removePolygon(jsi::Runtime &rt, double viewId, jsi::String id) = 0; + virtual jsi::Value removeCircle(jsi::Runtime &rt, double viewId, jsi::String id) = 0; + virtual jsi::Value removeGroundOverlay(jsi::Runtime &rt, double viewId, jsi::String id) = 0; + virtual jsi::Value setZoomLevel(jsi::Runtime &rt, double viewId, double level) = 0; + +}; + +template +class JSI_EXPORT NativeNavViewModuleCxxSpec : public TurboModule { +public: + jsi::Value create(jsi::Runtime &rt, const jsi::PropNameID &propName) override { + return delegate_.create(rt, propName); + } + + std::vector getPropertyNames(jsi::Runtime& runtime) override { + return delegate_.getPropertyNames(runtime); + } + + static constexpr std::string_view kModuleName = "NavViewModule"; + +protected: + NativeNavViewModuleCxxSpec(std::shared_ptr jsInvoker) + : TurboModule(std::string{NativeNavViewModuleCxxSpec::kModuleName}, jsInvoker), + delegate_(reinterpret_cast(this), jsInvoker) {} + + +private: + class Delegate : public NativeNavViewModuleCxxSpecJSI { + public: + Delegate(T *instance, std::shared_ptr jsInvoker) : + NativeNavViewModuleCxxSpecJSI(std::move(jsInvoker)), instance_(instance) { + + } + + jsi::Value addCircle(jsi::Runtime &rt, double viewId, jsi::Object options) override { + static_assert( + bridging::getParameterCount(&T::addCircle) == 3, + "Expected addCircle(...) to have 3 parameters"); + + return bridging::callFromJs( + rt, &T::addCircle, jsInvoker_, instance_, std::move(viewId), std::move(options)); + } + jsi::Value addMarker(jsi::Runtime &rt, double viewId, jsi::Object options) override { + static_assert( + bridging::getParameterCount(&T::addMarker) == 3, + "Expected addMarker(...) to have 3 parameters"); + + return bridging::callFromJs( + rt, &T::addMarker, jsInvoker_, instance_, std::move(viewId), std::move(options)); + } + jsi::Value addPolyline(jsi::Runtime &rt, double viewId, jsi::Object options) override { + static_assert( + bridging::getParameterCount(&T::addPolyline) == 3, + "Expected addPolyline(...) to have 3 parameters"); + + return bridging::callFromJs( + rt, &T::addPolyline, jsInvoker_, instance_, std::move(viewId), std::move(options)); + } + jsi::Value addPolygon(jsi::Runtime &rt, double viewId, jsi::Object options) override { + static_assert( + bridging::getParameterCount(&T::addPolygon) == 3, + "Expected addPolygon(...) to have 3 parameters"); + + return bridging::callFromJs( + rt, &T::addPolygon, jsInvoker_, instance_, std::move(viewId), std::move(options)); + } + jsi::Value addGroundOverlay(jsi::Runtime &rt, double viewId, jsi::Object options) override { + static_assert( + bridging::getParameterCount(&T::addGroundOverlay) == 3, + "Expected addGroundOverlay(...) to have 3 parameters"); + + return bridging::callFromJs( + rt, &T::addGroundOverlay, jsInvoker_, instance_, std::move(viewId), std::move(options)); + } + jsi::Value moveCamera(jsi::Runtime &rt, double viewId, jsi::Object cameraPosition) override { + static_assert( + bridging::getParameterCount(&T::moveCamera) == 3, + "Expected moveCamera(...) to have 3 parameters"); + + return bridging::callFromJs( + rt, &T::moveCamera, jsInvoker_, instance_, std::move(viewId), std::move(cameraPosition)); + } + jsi::Value getCameraPosition(jsi::Runtime &rt, double viewId) override { + static_assert( + bridging::getParameterCount(&T::getCameraPosition) == 2, + "Expected getCameraPosition(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::getCameraPosition, jsInvoker_, instance_, std::move(viewId)); + } + jsi::Value getMyLocation(jsi::Runtime &rt, double viewId) override { + static_assert( + bridging::getParameterCount(&T::getMyLocation) == 2, + "Expected getMyLocation(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::getMyLocation, jsInvoker_, instance_, std::move(viewId)); + } + jsi::Value getUiSettings(jsi::Runtime &rt, double viewId) override { + static_assert( + bridging::getParameterCount(&T::getUiSettings) == 2, + "Expected getUiSettings(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::getUiSettings, jsInvoker_, instance_, std::move(viewId)); + } + jsi::Value isMyLocationEnabled(jsi::Runtime &rt, double viewId) override { + static_assert( + bridging::getParameterCount(&T::isMyLocationEnabled) == 2, + "Expected isMyLocationEnabled(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::isMyLocationEnabled, jsInvoker_, instance_, std::move(viewId)); + } + jsi::Value showRouteOverview(jsi::Runtime &rt, double viewId) override { + static_assert( + bridging::getParameterCount(&T::showRouteOverview) == 2, + "Expected showRouteOverview(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::showRouteOverview, jsInvoker_, instance_, std::move(viewId)); + } + jsi::Value clearMapView(jsi::Runtime &rt, double viewId) override { + static_assert( + bridging::getParameterCount(&T::clearMapView) == 2, + "Expected clearMapView(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::clearMapView, jsInvoker_, instance_, std::move(viewId)); + } + jsi::Value removeMarker(jsi::Runtime &rt, double viewId, jsi::String id) override { + static_assert( + bridging::getParameterCount(&T::removeMarker) == 3, + "Expected removeMarker(...) to have 3 parameters"); + + return bridging::callFromJs( + rt, &T::removeMarker, jsInvoker_, instance_, std::move(viewId), std::move(id)); + } + jsi::Value removePolyline(jsi::Runtime &rt, double viewId, jsi::String id) override { + static_assert( + bridging::getParameterCount(&T::removePolyline) == 3, + "Expected removePolyline(...) to have 3 parameters"); + + return bridging::callFromJs( + rt, &T::removePolyline, jsInvoker_, instance_, std::move(viewId), std::move(id)); + } + jsi::Value removePolygon(jsi::Runtime &rt, double viewId, jsi::String id) override { + static_assert( + bridging::getParameterCount(&T::removePolygon) == 3, + "Expected removePolygon(...) to have 3 parameters"); + + return bridging::callFromJs( + rt, &T::removePolygon, jsInvoker_, instance_, std::move(viewId), std::move(id)); + } + jsi::Value removeCircle(jsi::Runtime &rt, double viewId, jsi::String id) override { + static_assert( + bridging::getParameterCount(&T::removeCircle) == 3, + "Expected removeCircle(...) to have 3 parameters"); + + return bridging::callFromJs( + rt, &T::removeCircle, jsInvoker_, instance_, std::move(viewId), std::move(id)); + } + jsi::Value removeGroundOverlay(jsi::Runtime &rt, double viewId, jsi::String id) override { + static_assert( + bridging::getParameterCount(&T::removeGroundOverlay) == 3, + "Expected removeGroundOverlay(...) to have 3 parameters"); + + return bridging::callFromJs( + rt, &T::removeGroundOverlay, jsInvoker_, instance_, std::move(viewId), std::move(id)); + } + jsi::Value setZoomLevel(jsi::Runtime &rt, double viewId, double level) override { + static_assert( + bridging::getParameterCount(&T::setZoomLevel) == 3, + "Expected setZoomLevel(...) to have 3 parameters"); + + return bridging::callFromJs( + rt, &T::setZoomLevel, jsInvoker_, instance_, std::move(viewId), std::move(level)); + } + + private: + friend class NativeNavViewModuleCxxSpec; + T *instance_; + }; + + Delegate delegate_; +}; + +} // namespace facebook::react diff --git a/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/ShadowNodes.cpp b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/ShadowNodes.cpp new file mode 100644 index 00000000..0f99d685 --- /dev/null +++ b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/ShadowNodes.cpp @@ -0,0 +1,31 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateShadowNodeCpp.js + */ + +#include "ShadowNodes.h" + +namespace facebook::react { + +extern const char NavViewComponentName[] = "NavView"; + +} // namespace facebook::react diff --git a/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/ShadowNodes.h b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/ShadowNodes.h new file mode 100644 index 00000000..60282fe6 --- /dev/null +++ b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/ShadowNodes.h @@ -0,0 +1,48 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateShadowNodeH.js + */ + +#pragma once + +#include "EventEmitters.h" +#include "Props.h" +#include "States.h" +#include +#include + +namespace facebook::react { + +JSI_EXPORT extern const char NavViewComponentName[]; + +/* + * `ShadowNode` for component. + */ +using NavViewShadowNode = ConcreteViewShadowNode< + NavViewComponentName, + NavViewProps, + NavViewEventEmitter, + NavViewState>; + +} // namespace facebook::react diff --git a/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/States.cpp b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/States.cpp new file mode 100644 index 00000000..bf138974 --- /dev/null +++ b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/States.cpp @@ -0,0 +1,30 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateStateCpp.js + */ +#include "States.h" + +namespace facebook::react { + + + +} // namespace facebook::react diff --git a/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/States.h b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/States.h new file mode 100644 index 00000000..0a945dea --- /dev/null +++ b/android/generated/jni/react/renderer/components/RNNavigationSdkSpec/States.h @@ -0,0 +1,45 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). + * + * Do not edit this file as changes may cause incorrect behavior and will be lost + * once the code is regenerated. + * + * @generated by codegen project: GenerateStateH.js + */ +#pragma once + +#ifdef ANDROID +#include +#endif + +namespace facebook::react { + +class NavViewState { +public: + NavViewState() = default; + +#ifdef ANDROID + NavViewState(NavViewState const &previousState, folly::dynamic data){}; + folly::dynamic getDynamic() const { + return {}; + }; +#endif +}; + +} // namespace facebook::react \ No newline at end of file diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 00000000..e40049c6 --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,6 @@ +react_native_navigation_sdk_kotlinVersion=2.0.21 +react_native_navigation_sdk_minSdkVersion=23 +react_native_navigation_sdk_targetSdkVersion=34 +react_native_navigation_sdk_compileSdkVersion=35 +react_native_navigation_sdk_ndkVersion=27.1.12297006 +react_native_navigation_sdk_navSdkVersion=6.2.2 diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml index 5c664b46..be0f3e44 100644 --- a/android/src/main/AndroidManifest.xml +++ b/android/src/main/AndroidManifest.xml @@ -1,12 +1,11 @@ - - - - - - - - - - \ No newline at end of file + + diff --git a/ios/react-native-navigation-sdk.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/android/src/main/AndroidManifestNew.xml similarity index 69% rename from ios/react-native-navigation-sdk.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to android/src/main/AndroidManifestNew.xml index a950a5c1..c6da0ad8 100644 --- a/ios/react-native-navigation-sdk.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/android/src/main/AndroidManifestNew.xml @@ -1,12 +1,12 @@ - - - - - + + diff --git a/android/src/main/java/com/google/android/react/navsdk/Command.java b/android/src/main/java/com/google/android/react/navsdk/Command.java deleted file mode 100644 index 0b9931dd..00000000 --- a/android/src/main/java/com/google/android/react/navsdk/Command.java +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Copyright 2023 Google LLC - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.google.android.react.navsdk; - -import androidx.annotation.NonNull; - -public enum Command { - CREATE_FRAGMENT(1, "createFragment"), - MOVE_CAMERA(2, "moveCamera"), - SET_MY_LOCATION_ENABLED(3, "setMyLocationEnabled"), - SET_TRIP_PROGRESS_BAR_ENABLED(4, "setTripProgressBarEnabled"), - SET_NAVIGATION_UI_ENABLED(5, "setNavigationUIEnabled"), - SET_FOLLOWING_PERSPECTIVE(6, "setFollowingPerspective"), - SET_NIGHT_MODE(7, "setNightMode"), - DELETE_FRAGMENT(8, "deleteFragment"), - SET_SPEEDOMETER_ENABLED(9, "setSpeedometerEnabled"), - SET_SPEED_LIMIT_ICON_ENABLED(10, "setSpeedLimitIconEnabled"), - SET_ZOOM_LEVEL(11, "setZoomLevel"), - SET_INDOOR_ENABLED(12, "setIndoorEnabled"), - SET_TRAFFIC_ENABLED(13, "setTrafficEnabled"), - SET_COMPASS_ENABLED(14, "setCompassEnabled"), - SET_MY_LOCATION_BUTTON_ENABLED(15, "setMyLocationButtonEnabled"), - SET_ROTATE_GESTURES_ENABLED(16, "setRotateGesturesEnabled"), - SET_SCROLL_GESTURES_ENABLED(17, "setScrollGesturesEnabled"), - SET_SCROLL_GESTURES_ENABLED_DURING_ROTATE_OR_ZOOM( - 18, "setScrollGesturesEnabledDuringRotateOrZoom"), - SET_TILT_GESTURES_ENABLED(19, "setTiltGesturesEnabled"), - SET_ZOOM_GESTURES_ENABLED(20, "setZoomGesturesEnabled"), - SET_BUILDINGS_ENABLED(21, "setBuildingsEnabled"), - SET_MAP_TYPE(22, "setMapType"), - SET_MAP_TOOLBAR_ENABLED(23, "setMapToolbarEnabled"), - CLEAR_MAP_VIEW(24, "clearMapView"), - RESET_MIN_MAX_ZOOM_LEVEL(25, "resetMinMaxZoomLevel"), - SET_MAP_STYLE(26, "setMapStyle"), - ANIMATE_CAMERA(27, "animateCamera"), - SHOW_ROUTE_OVERVIEW(28, "showRouteOverview"), - SET_TRAFFIC_INCIDENT_CARDS_ENABLED(29, "setTrafficIncidentCardsEnabled"), - SET_FOOTER_ENABLED(30, "setFooterEnabled"), - SET_HEADER_ENABLED(31, "setHeaderEnabled"), - REMOVE_MARKER(32, "removeMarker"), - REMOVE_POLYLINE(33, "removePolyline"), - REMOVE_POLYGON(34, "removePolygon"), - REMOVE_CIRCLE(35, "removeCircle"), - REMOVE_GROUND_OVERLAY(36, "removeGroundOverlay"), - SET_ZOOM_CONTROLS_ENABLED(37, "setZoomControlsEnabled"), - SET_RECENTER_BUTTON_ENABLED(38, "setRecenterButtonEnabled"), - SET_PADDING(39, "setPadding"); - - private final int value; - private final String name; - - Command(int value, String name) { - this.value = value; - this.name = name; - } - - public int getValue() { - return value; - } - - @NonNull - public String toString() { - return this.name; - } - - public static Command find(int value) { - for (Command i : Command.values()) { - if (i.value == value) return i; - } - return null; - } -} diff --git a/android/src/main/java/com/google/android/react/navsdk/INavigationViewCallback.java b/android/src/main/java/com/google/android/react/navsdk/INavigationViewCallback.java deleted file mode 100644 index f51c993e..00000000 --- a/android/src/main/java/com/google/android/react/navsdk/INavigationViewCallback.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright 2023 Google LLC - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.google.android.react.navsdk; - -import com.google.android.gms.maps.model.Circle; -import com.google.android.gms.maps.model.GroundOverlay; -import com.google.android.gms.maps.model.LatLng; -import com.google.android.gms.maps.model.Marker; -import com.google.android.gms.maps.model.Polygon; -import com.google.android.gms.maps.model.Polyline; - -public interface INavigationViewCallback { - void onMapReady(); - - void onRecenterButtonClick(); - - void onMarkerClick(Marker marker); - - void onPolylineClick(Polyline polyline); - - void onPolygonClick(Polygon polygon); - - void onCircleClick(Circle circle); - - void onGroundOverlayClick(GroundOverlay groundOverlay); - - void onMarkerInfoWindowTapped(Marker marker); - - void onMapClick(LatLng latLng); -} diff --git a/android/src/main/java/com/google/android/react/navsdk/JsErrors.java b/android/src/main/java/com/google/android/react/navsdk/JsErrors.java deleted file mode 100644 index 585ef18a..00000000 --- a/android/src/main/java/com/google/android/react/navsdk/JsErrors.java +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Copyright 2023 Google LLC - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.google.android.react.navsdk; - -public class JsErrors { - public static final String NO_NAVIGATOR_ERROR_CODE = "NO_NAVIGATOR_ERROR_CODE"; - public static final String NO_NAVIGATOR_ERROR_MESSAGE = - "Make sure to initialize the navigator is ready before executing."; - - public static final String NO_MAP_ERROR_CODE = "NO_MAP_ERROR_CODE"; - public static final String NO_MAP_ERROR_MESSAGE = - "Make sure to initialize the map view has been initialized before executing."; -} diff --git a/android/src/main/java/com/google/android/react/navsdk/MapViewController.java b/android/src/main/java/com/google/android/react/navsdk/MapViewController.java deleted file mode 100644 index f88881e1..00000000 --- a/android/src/main/java/com/google/android/react/navsdk/MapViewController.java +++ /dev/null @@ -1,578 +0,0 @@ -/** - * Copyright 2024 Google LLC - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.google.android.react.navsdk; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.graphics.Color; -import androidx.core.util.Supplier; -import com.facebook.react.bridge.UiThreadUtil; -import com.google.android.gms.maps.CameraUpdateFactory; -import com.google.android.gms.maps.GoogleMap; -import com.google.android.gms.maps.model.BitmapDescriptor; -import com.google.android.gms.maps.model.BitmapDescriptorFactory; -import com.google.android.gms.maps.model.CameraPosition; -import com.google.android.gms.maps.model.Circle; -import com.google.android.gms.maps.model.CircleOptions; -import com.google.android.gms.maps.model.GroundOverlay; -import com.google.android.gms.maps.model.GroundOverlayOptions; -import com.google.android.gms.maps.model.LatLng; -import com.google.android.gms.maps.model.MapStyleOptions; -import com.google.android.gms.maps.model.Marker; -import com.google.android.gms.maps.model.MarkerOptions; -import com.google.android.gms.maps.model.Polygon; -import com.google.android.gms.maps.model.PolygonOptions; -import com.google.android.gms.maps.model.Polyline; -import com.google.android.gms.maps.model.PolylineOptions; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Executors; - -public class MapViewController { - private GoogleMap mGoogleMap; - private Supplier activitySupplier; - private INavigationViewCallback mNavigationViewCallback; - private final List markerList = new ArrayList<>(); - private final List polylineList = new ArrayList<>(); - private final List polygonList = new ArrayList<>(); - private final List groundOverlayList = new ArrayList<>(); - private final List circleList = new ArrayList<>(); - private String style = ""; - - public void initialize(GoogleMap googleMap, Supplier activitySupplier) { - this.mGoogleMap = googleMap; - this.activitySupplier = activitySupplier; - } - - public void setupMapListeners(INavigationViewCallback navigationViewCallback) { - this.mNavigationViewCallback = navigationViewCallback; - if (mGoogleMap == null || mNavigationViewCallback == null) return; - - mGoogleMap.setOnMarkerClickListener( - marker -> { - mNavigationViewCallback.onMarkerClick(marker); - return false; - }); - - mGoogleMap.setOnPolylineClickListener( - polyline -> mNavigationViewCallback.onPolylineClick(polyline)); - mGoogleMap.setOnPolygonClickListener( - polygon -> mNavigationViewCallback.onPolygonClick(polygon)); - mGoogleMap.setOnCircleClickListener(circle -> mNavigationViewCallback.onCircleClick(circle)); - mGoogleMap.setOnGroundOverlayClickListener( - groundOverlay -> mNavigationViewCallback.onGroundOverlayClick(groundOverlay)); - mGoogleMap.setOnInfoWindowClickListener( - marker -> mNavigationViewCallback.onMarkerInfoWindowTapped(marker)); - mGoogleMap.setOnMapClickListener(latLng -> mNavigationViewCallback.onMapClick(latLng)); - } - - public GoogleMap getGoogleMap() { - return mGoogleMap; - } - - public Circle addCircle(Map optionsMap) { - if (mGoogleMap == null) { - return null; - } - - CircleOptions options = new CircleOptions(); - - float strokeWidth = - Double.valueOf(CollectionUtil.getDouble("strokeWidth", optionsMap, 0)).floatValue(); - options.strokeWidth(strokeWidth); - - double radius = CollectionUtil.getDouble("radius", optionsMap, 0.0); - options.radius(radius); - - boolean visible = CollectionUtil.getBool("visible", optionsMap, true); - options.visible(visible); - - options.center( - ObjectTranslationUtil.getLatLngFromMap((Map) optionsMap.get("center"))); - - boolean clickable = CollectionUtil.getBool("clickable", optionsMap, false); - options.clickable(clickable); - - String strokeColor = CollectionUtil.getString("strokeColor", optionsMap); - if (strokeColor != null) { - options.strokeColor(Color.parseColor(strokeColor)); - } - - String fillColor = CollectionUtil.getString("fillColor", optionsMap); - if (fillColor != null) { - options.fillColor(Color.parseColor(fillColor)); - } - - Circle circle = mGoogleMap.addCircle(options); - circleList.add(circle); - - return circle; - } - - public Marker addMarker(Map optionsMap) { - if (mGoogleMap == null) { - return null; - } - - String imagePath = CollectionUtil.getString("imgPath", optionsMap); - String title = CollectionUtil.getString("title", optionsMap); - String snippet = CollectionUtil.getString("snippet", optionsMap); - float alpha = Double.valueOf(CollectionUtil.getDouble("alpha", optionsMap, 1)).floatValue(); - float rotation = - Double.valueOf(CollectionUtil.getDouble("rotation", optionsMap, 0)).floatValue(); - boolean draggable = CollectionUtil.getBool("draggable", optionsMap, false); - boolean flat = CollectionUtil.getBool("flat", optionsMap, false); - boolean visible = CollectionUtil.getBool("visible", optionsMap, true); - - MarkerOptions options = new MarkerOptions(); - if (imagePath != null && !imagePath.isEmpty()) { - BitmapDescriptor icon = BitmapDescriptorFactory.fromAsset(imagePath); - options.icon(icon); - } - - options.position( - ObjectTranslationUtil.getLatLngFromMap((Map) optionsMap.get("position"))); - - if (title != null) { - options.title(title); - } - - if (snippet != null) { - options.snippet(snippet); - } - - options.flat(flat); - options.alpha(alpha); - options.rotation(rotation); - options.draggable(draggable); - options.visible(visible); - - Marker marker = mGoogleMap.addMarker(options); - - markerList.add(marker); - - return marker; - } - - public Polyline addPolyline(Map optionsMap) { - if (mGoogleMap == null) { - return null; - } - - float width = Double.valueOf(CollectionUtil.getDouble("width", optionsMap, 0)).floatValue(); - boolean clickable = CollectionUtil.getBool("clickable", optionsMap, false); - boolean visible = CollectionUtil.getBool("visible", optionsMap, true); - - ArrayList latLngArr = (ArrayList) optionsMap.get("points"); - - if (latLngArr == null) { - return null; - } - - PolylineOptions options = new PolylineOptions(); - for (int i = 0; i < latLngArr.size(); i++) { - Map latLngMap = (Map) latLngArr.get(i); - LatLng latLng = createLatLng(latLngMap); - options.add(latLng); - } - - String color = CollectionUtil.getString("color", optionsMap); - if (color != null) { - options.color(Color.parseColor(color)); - } - - options.width(width); - options.clickable(clickable); - options.visible(visible); - - Polyline polyline = mGoogleMap.addPolyline(options); - polylineList.add(polyline); - - return polyline; - } - - public Polygon addPolygon(Map optionsMap) { - if (mGoogleMap == null) { - return null; - } - - String strokeColor = CollectionUtil.getString("strokeColor", optionsMap); - String fillColor = CollectionUtil.getString("fillColor", optionsMap); - float strokeWidth = - Double.valueOf(CollectionUtil.getDouble("strokeWidth", optionsMap, 0)).floatValue(); - boolean clickable = CollectionUtil.getBool("clickable", optionsMap, false); - boolean geodesic = CollectionUtil.getBool("geodesic", optionsMap, false); - boolean visible = CollectionUtil.getBool("visible", optionsMap, true); - - ArrayList latLngArr = (ArrayList) optionsMap.get("points"); - - PolygonOptions options = new PolygonOptions(); - for (int i = 0; i < latLngArr.size(); i++) { - Map latLngMap = (Map) latLngArr.get(i); - LatLng latLng = createLatLng(latLngMap); - options.add(latLng); - } - - ArrayList holesArr = (ArrayList) optionsMap.get("holes"); - - for (int i = 0; i < holesArr.size(); i++) { - ArrayList arr = (ArrayList) holesArr.get(i); - - List listHoles = new ArrayList<>(); - - for (int j = 0; j < arr.size(); j++) { - Map latLngMap = (Map) arr.get(j); - LatLng latLng = createLatLng(latLngMap); - - listHoles.add(latLng); - } - - options.addHole(listHoles); - } - - if (fillColor != null) { - options.fillColor(Color.parseColor(fillColor)); - } - - if (strokeColor != null) { - options.strokeColor(Color.parseColor(strokeColor)); - } - - options.strokeWidth(strokeWidth); - options.visible(visible); - options.geodesic(geodesic); - options.clickable(clickable); - - Polygon polygon = mGoogleMap.addPolygon(options); - polygonList.add(polygon); - - return polygon; - } - - public GroundOverlay addGroundOverlay(Map map) { - if (mGoogleMap == null) { - return null; - } - - String imagePath = CollectionUtil.getString("imgPath", map); - float width = Double.valueOf(CollectionUtil.getDouble("width", map, 0)).floatValue(); - float height = Double.valueOf(CollectionUtil.getDouble("height", map, 0)).floatValue(); - float transparency = - Double.valueOf(CollectionUtil.getDouble("transparency", map, 0)).floatValue(); - boolean clickable = CollectionUtil.getBool("clickable", map, false); - boolean visible = CollectionUtil.getBool("visible", map, true); - - Double lat = null; - Double lng = null; - if (map.containsKey("location")) { - Map latlng = (Map) map.get("location"); - if (latlng.get("lat") != null) lat = Double.parseDouble(latlng.get("lat").toString()); - if (latlng.get("lng") != null) lng = Double.parseDouble(latlng.get("lng").toString()); - } - - GroundOverlayOptions options = new GroundOverlayOptions(); - if (imagePath != null && !imagePath.isEmpty()) { - BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromAsset(imagePath); - options.image(bitmapDescriptor); - } - options.position(new LatLng(lat, lng), width, height); - options.transparency(transparency); - options.clickable(clickable); - options.visible(visible); - GroundOverlay groundOverlay = mGoogleMap.addGroundOverlay(options); - groundOverlayList.add(groundOverlay); - return groundOverlay; - } - - public void removeMarker(String id) { - UiThreadUtil.runOnUiThread( - () -> { - for (Marker m : markerList) { - if (m.getId().equals(id)) { - m.remove(); - markerList.remove(m); - return; - } - } - }); - } - - public void removePolyline(String id) { - for (Polyline p : polylineList) { - if (p.getId().equals(id)) { - p.remove(); - polylineList.remove(p); - return; - } - } - } - - public void removePolygon(String id) { - for (Polygon p : polygonList) { - if (p.getId().equals(id)) { - p.remove(); - polygonList.remove(p); - return; - } - } - } - - public void removeCircle(String id) { - for (Circle c : circleList) { - if (c.getId().equals(id)) { - c.remove(); - circleList.remove(c); - return; - } - } - } - - public void removeGroundOverlay(String id) { - for (GroundOverlay g : groundOverlayList) { - if (g.getId().equals(id)) { - g.remove(); - groundOverlayList.remove(g); - return; - } - } - } - - public void setMapStyle(String url) { - Executors.newSingleThreadExecutor() - .execute( - () -> { - try { - style = fetchJsonFromUrl(url); - } catch (IOException e) { - throw new RuntimeException(e); - } - - Activity activity = activitySupplier.get(); - if (activity != null) { - activity.runOnUiThread( - () -> { - MapStyleOptions options = new MapStyleOptions(style); - mGoogleMap.setMapStyle(options); - }); - } - }); - } - - /** Moves the position of the camera to hover over Melbourne. */ - public void moveCamera(Map map) { - LatLng latLng = ObjectTranslationUtil.getLatLngFromMap((Map) map.get("target")); - - float zoom = (float) CollectionUtil.getDouble("zoom", map, 0); - float tilt = (float) CollectionUtil.getDouble("tilt", map, 0); - float bearing = (float) CollectionUtil.getDouble("bearing", map, 0); - - CameraPosition cameraPosition = - CameraPosition.builder().target(latLng).zoom(zoom).tilt(tilt).bearing(bearing).build(); - - mGoogleMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); - } - - public void animateCamera(Map map) { - if (mGoogleMap != null) { - int zoom = CollectionUtil.getInt("zoom", map, 0); - int tilt = CollectionUtil.getInt("tilt", map, 0); - int bearing = CollectionUtil.getInt("bearing", map, 0); - int animationDuration = CollectionUtil.getInt("duration", map, 0); - - CameraPosition cameraPosition = - new CameraPosition.Builder() - .target( - ObjectTranslationUtil.getLatLngFromMap( - (Map) map.get("target"))) // Set the target location - .zoom(zoom) // Set the desired zoom level - .tilt(tilt) // Set the desired tilt angle (0 for straight down, 90 for straight up) - .bearing(bearing) // Set the desired bearing (rotation angle in degrees) - .build(); - - mGoogleMap.animateCamera( - CameraUpdateFactory.newCameraPosition(cameraPosition), animationDuration, null); - } - } - - public void setZoomLevel(int level) { - if (mGoogleMap != null) { - mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(level)); - } - } - - public void setIndoorEnabled(boolean isOn) { - if (mGoogleMap != null) { - mGoogleMap.setIndoorEnabled(isOn); - } - } - - public void setTrafficEnabled(boolean isOn) { - if (mGoogleMap != null) { - mGoogleMap.setTrafficEnabled(isOn); - } - } - - public void setCompassEnabled(boolean isOn) { - if (mGoogleMap != null) { - mGoogleMap.getUiSettings().setCompassEnabled(isOn); - } - } - - public void setRotateGesturesEnabled(boolean isOn) { - if (mGoogleMap != null) { - mGoogleMap.getUiSettings().setRotateGesturesEnabled(isOn); - } - } - - public void setScrollGesturesEnabled(boolean isOn) { - if (mGoogleMap != null) { - mGoogleMap.getUiSettings().setScrollGesturesEnabled(isOn); - } - } - - public void setScrollGesturesEnabledDuringRotateOrZoom(boolean isOn) { - if (mGoogleMap != null) { - mGoogleMap.getUiSettings().setScrollGesturesEnabledDuringRotateOrZoom(isOn); - } - } - - public void setTiltGesturesEnabled(boolean isOn) { - if (mGoogleMap != null) { - mGoogleMap.getUiSettings().setTiltGesturesEnabled(isOn); - } - } - - public void setZoomControlsEnabled(boolean isOn) { - if (mGoogleMap != null) { - mGoogleMap.getUiSettings().setZoomControlsEnabled(isOn); - } - } - - public void setZoomGesturesEnabled(boolean isOn) { - if (mGoogleMap != null) { - mGoogleMap.getUiSettings().setZoomGesturesEnabled(isOn); - } - } - - public void setBuildingsEnabled(boolean isOn) { - if (mGoogleMap != null) { - mGoogleMap.setBuildingsEnabled(isOn); - } - } - - @SuppressLint("MissingPermission") - public void setMyLocationEnabled(boolean isOn) { - if (mGoogleMap != null) { - mGoogleMap.setMyLocationEnabled(isOn); - } - } - - public void setMapToolbarEnabled(boolean isOn) { - if (mGoogleMap != null) { - mGoogleMap.getUiSettings().setMapToolbarEnabled(isOn); - } - } - - /** Toggles whether the location marker is enabled. */ - public void setMyLocationButtonEnabled(boolean isOn) { - if (mGoogleMap == null) { - return; - } - - UiThreadUtil.runOnUiThread( - () -> { - mGoogleMap.getUiSettings().setMyLocationButtonEnabled(isOn); - }); - } - - public void setMapType(int jsValue) { - if (mGoogleMap == null) { - return; - } - - mGoogleMap.setMapType(EnumTranslationUtil.getMapTypeFromJsValue(jsValue)); - } - - public void clearMapView() { - if (mGoogleMap == null) { - return; - } - - mGoogleMap.clear(); - } - - public void resetMinMaxZoomLevel() { - if (mGoogleMap == null) { - return; - } - - mGoogleMap.resetMinMaxZoomPreference(); - } - - @SuppressLint("MissingPermission") - public void setFollowingPerspective(int jsValue) { - if (mGoogleMap == null) { - return; - } - - mGoogleMap.followMyLocation(EnumTranslationUtil.getCameraPerspectiveFromJsValue(jsValue)); - } - - public void setPadding(int top, int left, int bottom, int right) { - if (mGoogleMap != null) { - mGoogleMap.setPadding(left, top, right, bottom); - } - } - - private String fetchJsonFromUrl(String urlString) throws IOException { - URL url = new URL(urlString); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - - int responseCode = connection.getResponseCode(); - if (responseCode == HttpURLConnection.HTTP_OK) { - InputStream inputStream = connection.getInputStream(); - BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); - StringBuilder stringBuilder = new StringBuilder(); - String line; - while ((line = reader.readLine()) != null) { - stringBuilder.append(line); - } - reader.close(); - inputStream.close(); - return stringBuilder.toString(); - } else { - // Handle error response - throw new IOException("Error response: " + responseCode); - } - } - - private LatLng createLatLng(Map map) { - Double lat = null; - Double lng = null; - if (map.containsKey("lat") && map.containsKey("lng")) { - if (map.get("lat") != null) lat = Double.parseDouble(map.get("lat").toString()); - if (map.get("lng") != null) lng = Double.parseDouble(map.get("lng").toString()); - } - - return new LatLng(lat, lng); - } -} diff --git a/android/src/main/java/com/google/android/react/navsdk/NavViewManager.java b/android/src/main/java/com/google/android/react/navsdk/NavViewManager.java deleted file mode 100644 index 03f40d74..00000000 --- a/android/src/main/java/com/google/android/react/navsdk/NavViewManager.java +++ /dev/null @@ -1,410 +0,0 @@ -/** - * Copyright 2023 Google LLC - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.google.android.react.navsdk; - -import static com.google.android.react.navsdk.Command.*; -import static com.google.android.react.navsdk.EnumTranslationUtil.getFragmentTypeFromJsValue; - -import android.view.Choreographer; -import android.view.View; -import android.view.ViewGroup; -import android.widget.FrameLayout; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentActivity; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.common.MapBuilder; -import com.facebook.react.uimanager.SimpleViewManager; -import com.facebook.react.uimanager.ThemedReactContext; -import com.google.android.gms.maps.GoogleMap; -import java.lang.ref.WeakReference; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -// NavViewManager is responsible for managing both the regular map fragment as well as the -// navigation map view fragment. -// -public class NavViewManager extends SimpleViewManager { - - public static final String REACT_CLASS = "NavViewManager"; - - private static NavViewManager instance; - - private final HashMap> fragmentMap = new HashMap<>(); - - private ReactApplicationContext reactContext; - - public static synchronized NavViewManager getInstance(ReactApplicationContext reactContext) { - if (instance == null) { - instance = new NavViewManager(); - } - instance.setReactContext(reactContext); - return instance; - } - - @NonNull - @Override - public String getName() { - return REACT_CLASS; - } - - public void setReactContext(ReactApplicationContext reactContext) { - this.reactContext = reactContext; - } - - /** Return a FrameLayout which will later hold the Fragment */ - @Override - public FrameLayout createViewInstance(ThemedReactContext reactContext) { - return new FrameLayout(reactContext); - } - - /** Map the "create" command to an integer */ - @Nullable - @Override - public Map getCommandsMap() { - Map map = new HashMap<>(); - map.put(CREATE_FRAGMENT.toString(), CREATE_FRAGMENT.getValue()); - map.put(MOVE_CAMERA.toString(), MOVE_CAMERA.getValue()); - map.put(SET_TRIP_PROGRESS_BAR_ENABLED.toString(), SET_TRIP_PROGRESS_BAR_ENABLED.getValue()); - map.put(SET_NAVIGATION_UI_ENABLED.toString(), SET_NAVIGATION_UI_ENABLED.getValue()); - map.put(SET_FOLLOWING_PERSPECTIVE.toString(), SET_FOLLOWING_PERSPECTIVE.getValue()); - map.put(SET_NIGHT_MODE.toString(), SET_NIGHT_MODE.getValue()); - map.put(DELETE_FRAGMENT.toString(), DELETE_FRAGMENT.getValue()); - map.put(SET_SPEEDOMETER_ENABLED.toString(), SET_SPEEDOMETER_ENABLED.getValue()); - map.put(SET_SPEED_LIMIT_ICON_ENABLED.toString(), SET_SPEED_LIMIT_ICON_ENABLED.getValue()); - map.put(SET_ZOOM_LEVEL.toString(), SET_ZOOM_LEVEL.getValue()); - map.put(SET_INDOOR_ENABLED.toString(), SET_INDOOR_ENABLED.getValue()); - map.put(SET_TRAFFIC_ENABLED.toString(), SET_TRAFFIC_ENABLED.getValue()); - map.put(SET_COMPASS_ENABLED.toString(), SET_COMPASS_ENABLED.getValue()); - map.put(SET_MY_LOCATION_BUTTON_ENABLED.toString(), SET_MY_LOCATION_BUTTON_ENABLED.getValue()); - map.put(SET_MY_LOCATION_ENABLED.toString(), SET_MY_LOCATION_ENABLED.getValue()); - map.put(SET_ROTATE_GESTURES_ENABLED.toString(), SET_ROTATE_GESTURES_ENABLED.getValue()); - map.put(SET_SCROLL_GESTURES_ENABLED.toString(), SET_SCROLL_GESTURES_ENABLED.getValue()); - map.put( - SET_SCROLL_GESTURES_ENABLED_DURING_ROTATE_OR_ZOOM.toString(), - SET_SCROLL_GESTURES_ENABLED_DURING_ROTATE_OR_ZOOM.getValue()); - map.put(SET_ZOOM_CONTROLS_ENABLED.toString(), SET_ZOOM_CONTROLS_ENABLED.getValue()); - map.put(SET_TILT_GESTURES_ENABLED.toString(), SET_TILT_GESTURES_ENABLED.getValue()); - map.put(SET_ZOOM_GESTURES_ENABLED.toString(), SET_ZOOM_GESTURES_ENABLED.getValue()); - map.put(SET_BUILDINGS_ENABLED.toString(), SET_BUILDINGS_ENABLED.getValue()); - map.put(SET_MAP_TYPE.toString(), SET_MAP_TYPE.getValue()); - map.put(SET_MAP_TOOLBAR_ENABLED.toString(), SET_MAP_TOOLBAR_ENABLED.getValue()); - map.put(CLEAR_MAP_VIEW.toString(), CLEAR_MAP_VIEW.getValue()); - map.put(RESET_MIN_MAX_ZOOM_LEVEL.toString(), RESET_MIN_MAX_ZOOM_LEVEL.getValue()); - map.put(SET_MAP_STYLE.toString(), SET_MAP_STYLE.getValue()); - map.put(ANIMATE_CAMERA.toString(), ANIMATE_CAMERA.getValue()); - map.put( - SET_TRAFFIC_INCIDENT_CARDS_ENABLED.toString(), - SET_TRAFFIC_INCIDENT_CARDS_ENABLED.getValue()); - map.put(SET_RECENTER_BUTTON_ENABLED.toString(), SET_RECENTER_BUTTON_ENABLED.getValue()); - map.put(SHOW_ROUTE_OVERVIEW.toString(), SHOW_ROUTE_OVERVIEW.getValue()); - map.put(REMOVE_MARKER.toString(), REMOVE_MARKER.getValue()); - map.put(REMOVE_POLYLINE.toString(), REMOVE_POLYLINE.getValue()); - map.put(REMOVE_POLYGON.toString(), REMOVE_POLYGON.getValue()); - map.put(REMOVE_CIRCLE.toString(), REMOVE_CIRCLE.getValue()); - map.put(REMOVE_GROUND_OVERLAY.toString(), REMOVE_GROUND_OVERLAY.getValue()); - map.put(SET_HEADER_ENABLED.toString(), SET_HEADER_ENABLED.getValue()); - map.put(SET_FOOTER_ENABLED.toString(), SET_FOOTER_ENABLED.getValue()); - map.put(SET_PADDING.toString(), SET_PADDING.getValue()); - return map; - } - - public INavViewFragment getNavFragmentForRoot(ViewGroup root) { - IMapViewFragment fragment = getFragmentForRoot(root); - - // Check if the fragment is an INavigationViewFragment - if (fragment instanceof INavViewFragment) { - return (INavViewFragment) fragment; - } else { - throw new IllegalStateException("The fragment is not a nav view fragment"); - } - } - - public IMapViewFragment getFragmentForRoot(ViewGroup root) { - int viewId = root.getId(); - return getFragmentForViewId(viewId); - } - - public IMapViewFragment getFragmentForViewId(int viewId) { - WeakReference weakReference = fragmentMap.get(viewId); - if (weakReference == null || weakReference.get() == null) { - throw new IllegalStateException("Fragment not found for the provided viewId."); - } - return weakReference.get(); - } - - public IMapViewFragment getAnyFragment() { - if (fragmentMap.isEmpty()) { - return null; - } - // Return the first fragment found in the map's values collection. - return fragmentMap.values().iterator().next().get(); - } - - public void applyStylingOptions() { - for (WeakReference weakReference : fragmentMap.values()) { - if (weakReference.get() != null) { - weakReference.get().applyStylingOptions(); - } - } - } - - @Override - public void receiveCommand( - @NonNull FrameLayout root, String commandId, @Nullable ReadableArray args) { - super.receiveCommand(root, commandId, args); - int commandIdInt = Integer.parseInt(commandId); - - switch (Command.find(commandIdInt)) { - case CREATE_FRAGMENT: - Map stylingOptions = args.getMap(0).toHashMap(); - CustomTypes.FragmentType fragmentType = getFragmentTypeFromJsValue(args.getInt(1)); - createFragment(root, stylingOptions, fragmentType); - break; - case DELETE_FRAGMENT: - try { - int viewId = root.getId(); - FragmentActivity activity = (FragmentActivity) reactContext.getCurrentActivity(); - IMapViewFragment fragment = Objects.requireNonNull(fragmentMap.remove(viewId)).get(); - activity - .getSupportFragmentManager() - .beginTransaction() - .remove((Fragment) fragment) - .commitNowAllowingStateLoss(); - } catch (Exception ignored) { - } - break; - case MOVE_CAMERA: - getFragmentForRoot(root).getMapController().moveCamera(args.getMap(0).toHashMap()); - break; - case SET_TRIP_PROGRESS_BAR_ENABLED: - getNavFragmentForRoot(root).setTripProgressBarEnabled(args.getBoolean(0)); - break; - case SET_NAVIGATION_UI_ENABLED: - getNavFragmentForRoot(root).setNavigationUiEnabled(args.getBoolean(0)); - break; - case SET_FOLLOWING_PERSPECTIVE: - getNavFragmentForRoot(root).getMapController().setFollowingPerspective(args.getInt(0)); - break; - case SET_NIGHT_MODE: - getNavFragmentForRoot(root).setNightModeOption(args.getInt(0)); - break; - case SET_SPEEDOMETER_ENABLED: - getNavFragmentForRoot(root).setSpeedometerEnabled(args.getBoolean(0)); - break; - case SET_SPEED_LIMIT_ICON_ENABLED: - getNavFragmentForRoot(root).setSpeedLimitIconEnabled(args.getBoolean(0)); - break; - case SET_ZOOM_LEVEL: - int level = args.getInt(0); - getFragmentForRoot(root).getMapController().setZoomLevel(level); - break; - case SET_INDOOR_ENABLED: - getFragmentForRoot(root).getMapController().setIndoorEnabled(args.getBoolean(0)); - break; - case SET_TRAFFIC_ENABLED: - getFragmentForRoot(root).getMapController().setTrafficEnabled(args.getBoolean(0)); - break; - case SET_COMPASS_ENABLED: - getFragmentForRoot(root).getMapController().setCompassEnabled(args.getBoolean(0)); - break; - case SET_MY_LOCATION_BUTTON_ENABLED: - getFragmentForRoot(root).getMapController().setCompassEnabled(args.getBoolean(0)); - break; - case SET_MY_LOCATION_ENABLED: - getFragmentForRoot(root).getMapController().setMyLocationEnabled(args.getBoolean(0)); - break; - case SET_ROTATE_GESTURES_ENABLED: - getFragmentForRoot(root).getMapController().setRotateGesturesEnabled(args.getBoolean(0)); - break; - case SET_SCROLL_GESTURES_ENABLED: - getFragmentForRoot(root).getMapController().setScrollGesturesEnabled(args.getBoolean(0)); - break; - case SET_SCROLL_GESTURES_ENABLED_DURING_ROTATE_OR_ZOOM: - getFragmentForRoot(root) - .getMapController() - .setScrollGesturesEnabledDuringRotateOrZoom(args.getBoolean(0)); - break; - case SET_TILT_GESTURES_ENABLED: - getFragmentForRoot(root).getMapController().setTiltGesturesEnabled(args.getBoolean(0)); - break; - case SET_ZOOM_CONTROLS_ENABLED: - getFragmentForRoot(root).getMapController().setZoomControlsEnabled(args.getBoolean(0)); - break; - case SET_ZOOM_GESTURES_ENABLED: - getFragmentForRoot(root).getMapController().setZoomGesturesEnabled(args.getBoolean(0)); - break; - case SET_BUILDINGS_ENABLED: - getFragmentForRoot(root).getMapController().setBuildingsEnabled(args.getBoolean(0)); - break; - case SET_MAP_TYPE: - getFragmentForRoot(root).getMapController().setMapType(args.getInt(0)); - break; - case SET_MAP_TOOLBAR_ENABLED: - getFragmentForRoot(root).getMapController().setMapToolbarEnabled(args.getBoolean(0)); - break; - case CLEAR_MAP_VIEW: - getFragmentForRoot(root).getMapController().clearMapView(); - break; - case RESET_MIN_MAX_ZOOM_LEVEL: - getFragmentForRoot(root).getMapController().resetMinMaxZoomLevel(); - break; - case SET_MAP_STYLE: - getFragmentForRoot(root).setMapStyle(args.getString(0)); - break; - case ANIMATE_CAMERA: - getFragmentForRoot(root).getMapController().animateCamera(args.getMap(0).toHashMap()); - break; - case SET_TRAFFIC_INCIDENT_CARDS_ENABLED: - getNavFragmentForRoot(root).setTrafficIncidentCardsEnabled(args.getBoolean(0)); - break; - case SET_FOOTER_ENABLED: - getNavFragmentForRoot(root).setEtaCardEnabled(args.getBoolean(0)); - break; - case SET_HEADER_ENABLED: - getNavFragmentForRoot(root).setHeaderEnabled(args.getBoolean(0)); - break; - case SET_RECENTER_BUTTON_ENABLED: - getNavFragmentForRoot(root).setRecenterButtonEnabled(args.getBoolean(0)); - break; - case SHOW_ROUTE_OVERVIEW: - getNavFragmentForRoot(root).showRouteOverview(); - break; - case REMOVE_MARKER: - getFragmentForRoot(root).getMapController().removeMarker(args.getString(0)); - break; - case REMOVE_POLYLINE: - getFragmentForRoot(root).getMapController().removePolyline(args.getString(0)); - break; - case REMOVE_POLYGON: - getFragmentForRoot(root).getMapController().removePolygon(args.getString(0)); - break; - case REMOVE_CIRCLE: - getFragmentForRoot(root).getMapController().removeCircle(args.getString(0)); - break; - case REMOVE_GROUND_OVERLAY: - getFragmentForRoot(root).getMapController().removeGroundOverlay(args.getString(0)); - break; - case SET_PADDING: - getFragmentForRoot(root) - .getMapController() - .setPadding(args.getInt(0), args.getInt(1), args.getInt(2), args.getInt(3)); - } - } - - @Override - public Map getExportedCustomDirectEventTypeConstants() { - Map baseEventTypeConstants = super.getExportedCustomDirectEventTypeConstants(); - Map eventTypeConstants = - baseEventTypeConstants != null ? baseEventTypeConstants : new HashMap<>(); - - ((Map) eventTypeConstants) - .putAll( - MapBuilder.builder() - .put( - "onRecenterButtonClick", - MapBuilder.of("registrationName", "onRecenterButtonClick")) - .put("onMapReady", MapBuilder.of("registrationName", "onMapReady")) - .put("onMapClick", MapBuilder.of("registrationName", "onMapClick")) - .put("onMarkerClick", MapBuilder.of("registrationName", "onMarkerClick")) - .put("onPolylineClick", MapBuilder.of("registrationName", "onPolylineClick")) - .put("onPolygonClick", MapBuilder.of("registrationName", "onPolygonClick")) - .put("onCircleClick", MapBuilder.of("registrationName", "onCircleClick")) - .put( - "onGroundOverlayClick", - MapBuilder.of("registrationName", "onGroundOverlayClick")) - .put( - "onMarkerInfoWindowTapped", - MapBuilder.of("registrationName", "onMarkerInfoWindowTapped")) - .build()); - return (Map) eventTypeConstants; - } - - /** Replace your React Native view with a custom fragment */ - public void createFragment( - FrameLayout root, Map stylingOptions, CustomTypes.FragmentType fragmentType) { - setupLayout(root); - - FragmentActivity activity = (FragmentActivity) reactContext.getCurrentActivity(); - if (activity != null) { - int viewId = root.getId(); - Fragment fragment; - // FragmentType 0 = MAP, 1 = NAVIGATION. - if (fragmentType == CustomTypes.FragmentType.MAP) { - MapViewFragment mapFragment = new MapViewFragment(reactContext, root.getId()); - fragmentMap.put(viewId, new WeakReference(mapFragment)); - fragment = mapFragment; - - if (stylingOptions != null) { - mapFragment.setStylingOptions(new StylingOptionsBuilder.Builder(stylingOptions).build()); - } - } else { - NavViewFragment navFragment = new NavViewFragment(reactContext, root.getId()); - fragmentMap.put(viewId, new WeakReference(navFragment)); - fragment = navFragment; - - if (stylingOptions != null) { - navFragment.setStylingOptions(new StylingOptionsBuilder.Builder(stylingOptions).build()); - } - } - activity - .getSupportFragmentManager() - .beginTransaction() - .replace(viewId, fragment, String.valueOf(viewId)) - .commit(); - } - } - - /** - * Set up the layout for each frame. This official RN way to do this, but a bit hacky, and should - * be changed when better solution is found. - */ - public void setupLayout(FrameLayout view) { - Choreographer.getInstance() - .postFrameCallback( - new Choreographer.FrameCallback() { - @Override - public void doFrame(long frameTimeNanos) { - manuallyLayoutChildren(view); - view.getViewTreeObserver().dispatchOnGlobalLayout(); - Choreographer.getInstance().postFrameCallback(this); - } - }); - } - - /** Layout all children properly */ - public void manuallyLayoutChildren(FrameLayout view) { - IMapViewFragment fragment = getFragmentForRoot(view); - if (fragment.isAdded()) { - View childView = fragment.getView(); - if (childView != null) { - childView.measure( - View.MeasureSpec.makeMeasureSpec(view.getMeasuredWidth(), View.MeasureSpec.EXACTLY), - View.MeasureSpec.makeMeasureSpec(view.getMeasuredHeight(), View.MeasureSpec.EXACTLY)); - childView.layout(0, 0, childView.getMeasuredWidth(), childView.getMeasuredHeight()); - } - } - } - - public GoogleMap getGoogleMap(int viewId) { - try { - return getFragmentForViewId(viewId).getGoogleMap(); - } catch (Exception e) { - return null; - } - } -} diff --git a/android/src/main/java/com/google/android/react/navsdk/NavViewModule.java b/android/src/main/java/com/google/android/react/navsdk/NavViewModule.java deleted file mode 100644 index 428599aa..00000000 --- a/android/src/main/java/com/google/android/react/navsdk/NavViewModule.java +++ /dev/null @@ -1,251 +0,0 @@ -/** - * Copyright 2023 Google LLC - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.google.android.react.navsdk; - -import android.location.Location; -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.UiThreadUtil; -import com.facebook.react.bridge.WritableMap; -import com.google.android.gms.maps.UiSettings; -import com.google.android.gms.maps.model.CameraPosition; -import com.google.android.gms.maps.model.Circle; -import com.google.android.gms.maps.model.GroundOverlay; -import com.google.android.gms.maps.model.LatLng; -import com.google.android.gms.maps.model.Marker; -import com.google.android.gms.maps.model.Polygon; -import com.google.android.gms.maps.model.Polyline; -import java.util.HashMap; -import java.util.Map; - -/** - * This exposes a series of methods that can be called diretly from the React Native code. They have - * been implemented using promises as it's not recommended for them to be synchronous. - */ -public class NavViewModule extends ReactContextBaseJavaModule { - - private static final String TAG = "NavViewModule"; - - private NavViewManager mNavViewManager; - - public NavViewModule(ReactApplicationContext reactContext, NavViewManager navViewManager) { - super(reactContext); - mNavViewManager = navViewManager; - } - - @Override - public String getName() { - return "NavViewModule"; - } - - @Override - public Map getConstants() { - final Map constants = new HashMap<>(); - return constants; - } - - @ReactMethod - public void getCameraPosition(Integer viewId, final Promise promise) { - UiThreadUtil.runOnUiThread( - () -> { - if (mNavViewManager.getGoogleMap(viewId) == null) { - promise.reject(JsErrors.NO_MAP_ERROR_CODE, JsErrors.NO_MAP_ERROR_MESSAGE); - return; - } - - CameraPosition cp = mNavViewManager.getGoogleMap(viewId).getCameraPosition(); - - if (cp == null) { - promise.resolve(null); - return; - } - - LatLng target = cp.target; - WritableMap map = Arguments.createMap(); - map.putDouble("bearing", cp.bearing); - map.putDouble("tilt", cp.tilt); - map.putDouble("zoom", cp.zoom); - map.putMap("target", ObjectTranslationUtil.getMapFromLatLng(target)); - - promise.resolve(map); - }); - } - - @ReactMethod - public void getMyLocation(Integer viewId, final Promise promise) { - UiThreadUtil.runOnUiThread( - () -> { - if (mNavViewManager.getGoogleMap(viewId) == null) { - promise.reject(JsErrors.NO_MAP_ERROR_CODE, JsErrors.NO_MAP_ERROR_MESSAGE); - return; - } - - try { - Location location = mNavViewManager.getGoogleMap(viewId).getMyLocation(); - if (location == null) { - promise.resolve(null); - return; - } - - promise.resolve(ObjectTranslationUtil.getMapFromLocation(location)); - } catch (Exception e) { - promise.resolve(null); - return; - } - }); - } - - @ReactMethod - public void getUiSettings(Integer viewId, final Promise promise) { - UiThreadUtil.runOnUiThread( - () -> { - if (mNavViewManager.getGoogleMap(viewId) == null) { - promise.reject(JsErrors.NO_MAP_ERROR_CODE, JsErrors.NO_MAP_ERROR_MESSAGE); - return; - } - - UiSettings settings = mNavViewManager.getGoogleMap(viewId).getUiSettings(); - - if (settings == null) { - promise.resolve(null); - return; - } - - WritableMap map = Arguments.createMap(); - map.putBoolean("isCompassEnabled", settings.isCompassEnabled()); - map.putBoolean("isMapToolbarEnabled", settings.isMapToolbarEnabled()); - map.putBoolean("isIndoorLevelPickerEnabled", settings.isIndoorLevelPickerEnabled()); - map.putBoolean("isRotateGesturesEnabled", settings.isRotateGesturesEnabled()); - map.putBoolean("isScrollGesturesEnabled", settings.isScrollGesturesEnabled()); - map.putBoolean( - "isScrollGesturesEnabledDuringRotateOrZoom", - settings.isScrollGesturesEnabledDuringRotateOrZoom()); - map.putBoolean("isTiltGesturesEnabled", settings.isTiltGesturesEnabled()); - map.putBoolean("isZoomControlsEnabled", settings.isZoomControlsEnabled()); - map.putBoolean("isZoomGesturesEnabled", settings.isZoomGesturesEnabled()); - - promise.resolve(map); - }); - } - - @ReactMethod - public void isMyLocationEnabled(Integer viewId, final Promise promise) { - UiThreadUtil.runOnUiThread( - () -> { - if (mNavViewManager.getGoogleMap(viewId) == null) { - promise.reject(JsErrors.NO_MAP_ERROR_CODE, JsErrors.NO_MAP_ERROR_MESSAGE); - return; - } - - promise.resolve(mNavViewManager.getGoogleMap(viewId).isMyLocationEnabled()); - }); - } - - @ReactMethod - public void addMarker(int viewId, ReadableMap markerOptionsMap, final Promise promise) { - UiThreadUtil.runOnUiThread( - () -> { - if (mNavViewManager.getGoogleMap(viewId) != null) { - Marker marker = - mNavViewManager - .getFragmentForViewId(viewId) - .getMapController() - .addMarker(markerOptionsMap.toHashMap()); - - promise.resolve(ObjectTranslationUtil.getMapFromMarker(marker)); - } - }); - } - - @ReactMethod - public void addPolyline(int viewId, ReadableMap polylineOptionsMap, final Promise promise) { - UiThreadUtil.runOnUiThread( - () -> { - if (mNavViewManager.getGoogleMap(viewId) == null) { - promise.reject(JsErrors.NO_MAP_ERROR_CODE, JsErrors.NO_MAP_ERROR_MESSAGE); - return; - } - Polyline polyline = - mNavViewManager - .getFragmentForViewId(viewId) - .getMapController() - .addPolyline(polylineOptionsMap.toHashMap()); - - promise.resolve(ObjectTranslationUtil.getMapFromPolyline(polyline)); - }); - } - - @ReactMethod - public void addPolygon(int viewId, ReadableMap polygonOptionsMap, final Promise promise) { - UiThreadUtil.runOnUiThread( - () -> { - if (mNavViewManager.getGoogleMap(viewId) == null) { - promise.reject(JsErrors.NO_MAP_ERROR_CODE, JsErrors.NO_MAP_ERROR_MESSAGE); - return; - } - Polygon polygon = - mNavViewManager - .getFragmentForViewId(viewId) - .getMapController() - .addPolygon(polygonOptionsMap.toHashMap()); - - promise.resolve(ObjectTranslationUtil.getMapFromPolygon(polygon)); - }); - } - - @ReactMethod - public void addCircle(int viewId, ReadableMap circleOptionsMap, final Promise promise) { - UiThreadUtil.runOnUiThread( - () -> { - if (mNavViewManager.getGoogleMap(viewId) == null) { - promise.reject(JsErrors.NO_MAP_ERROR_CODE, JsErrors.NO_MAP_ERROR_MESSAGE); - return; - } - Circle circle = - mNavViewManager - .getFragmentForViewId(viewId) - .getMapController() - .addCircle(circleOptionsMap.toHashMap()); - - promise.resolve(ObjectTranslationUtil.getMapFromCircle(circle)); - }); - } - - @ReactMethod - public void addGroundOverlay(int viewId, ReadableMap overlayOptionsMap, final Promise promise) { - UiThreadUtil.runOnUiThread( - () -> { - if (mNavViewManager.getGoogleMap(viewId) == null) { - promise.reject(JsErrors.NO_MAP_ERROR_CODE, JsErrors.NO_MAP_ERROR_MESSAGE); - return; - } - GroundOverlay overlay = - mNavViewManager - .getFragmentForViewId(viewId) - .getMapController() - .addGroundOverlay(overlayOptionsMap.toHashMap()); - - promise.resolve(ObjectTranslationUtil.getMapFromGroundOverlay(overlay)); - }); - } - - @Override - public boolean canOverrideExistingModule() { - return true; - } -} diff --git a/android/src/main/java/com/google/android/react/navsdk/Package.java b/android/src/main/java/com/google/android/react/navsdk/Package.java deleted file mode 100644 index d8478a56..00000000 --- a/android/src/main/java/com/google/android/react/navsdk/Package.java +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright 2023 Google LLC - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.google.android.react.navsdk; - -import com.facebook.proguard.annotations.DoNotStrip; -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.ViewManager; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -@DoNotStrip -public class Package implements ReactPackage { - - private NavViewManager mNavViewManager; - - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - return Arrays.asList(NavViewManager.getInstance(reactContext)); - } - - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - List modules = new ArrayList<>(); - NavViewManager viewManager = NavViewManager.getInstance(reactContext); - modules.add(NavModule.getInstance(reactContext, viewManager)); - modules.add(new NavAutoModule(reactContext)); - modules.add(new NavViewModule(reactContext, viewManager)); - - return modules; - } -} diff --git a/android/src/main/java/com/google/android/react/navsdk/AndroidAutoBaseScreen.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNAndroidAutoBaseScreen.java similarity index 82% rename from android/src/main/java/com/google/android/react/navsdk/AndroidAutoBaseScreen.java rename to android/src/main/java/com/google/maps/android/rn/navsdk/GMNAndroidAutoBaseScreen.java index f541c2a0..b2a085e7 100644 --- a/android/src/main/java/com/google/android/react/navsdk/AndroidAutoBaseScreen.java +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNAndroidAutoBaseScreen.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.android.react.navsdk; +package com.google.maps.android.rn.navsdk; import android.app.Presentation; import android.graphics.Point; @@ -50,8 +50,8 @@ // documentation: // https://developers.google.com/maps/documentation/navigation/android-sdk/android-auto @DoNotStrip -public abstract class AndroidAutoBaseScreen extends Screen - implements SurfaceCallback, INavigationViewController { +public abstract class GMNAndroidAutoBaseScreen extends Screen + implements SurfaceCallback, IGMNNavigationViewController { private static final String VIRTUAL_DISPLAY_NAME = "AndroidAutoNavScreen"; private NavigationViewForAuto mNavigationView; @@ -59,66 +59,61 @@ public abstract class AndroidAutoBaseScreen extends Screen private Presentation mPresentation; protected GoogleMap mGoogleMap; protected boolean mNavigationInitialized = false; - private MapViewController mMapViewController; + private GMNMapViewController mMapViewController; private boolean mAndroidAutoModuleInitialized = false; private boolean mNavModuleInitialized = false; - private final AndroidAutoBaseScreen screenInstance = this; - - @Override - public void setStylingOptions(StylingOptions stylingOptions) { - // TODO(jokerttu): set styling to the navigationView - } + private final GMNAndroidAutoBaseScreen screenInstance = this; public void onNavigationReady(boolean ready) { mNavigationInitialized = ready; } - public AndroidAutoBaseScreen(@NonNull CarContext carContext) { + public GMNAndroidAutoBaseScreen(@NonNull CarContext carContext) { super(carContext); - NavAutoModule.setModuleReadyListener( + GMNNavAutoModule.setModuleReadyListener( () -> { mAndroidAutoModuleInitialized = true; registerControllersForAndroidAutoModule(); }); - NavModule.setModuleReadyListener( + GMNNavModule.setModuleReadyListener( () -> { mNavModuleInitialized = true; - NavModule.getInstance().registerNavigationReadyListener(this::onNavigationReady); + GMNNavModule.getInstance().registerNavigationReadyListener(this::onNavigationReady); }); carContext.getCarService(AppManager.class).setSurfaceCallback(this); Lifecycle lifecycle = getLifecycle(); - lifecycle.addObserver(mLifeCycleObserver); - } - - private final LifecycleObserver mLifeCycleObserver = - new DefaultLifecycleObserver() { - @Override - public void onDestroy(@NonNull LifecycleOwner lifecycleOwner) { - if (mNavModuleInitialized) { - try { - NavModule.getInstance() - .unRegisterNavigationReadyListener(screenInstance::onNavigationReady); - } catch (Exception e) { + LifecycleObserver mLifeCycleObserver = + new DefaultLifecycleObserver() { + @Override + public void onDestroy(@NonNull LifecycleOwner lifecycleOwner) { + if (mNavModuleInitialized) { + try { + GMNNavModule.getInstance() + .unRegisterNavigationReadyListener(screenInstance::onNavigationReady); + } catch (Exception ignored) { + } } } - } - }; + }; + lifecycle.addObserver(mLifeCycleObserver); + } private void registerControllersForAndroidAutoModule() { if (mAndroidAutoModuleInitialized && mMapViewController != null) { - NavAutoModule.getInstance().androidAutoNavigationScreenInitialized(mMapViewController, this); + GMNNavAutoModule.getInstance() + .androidAutoNavigationScreenInitialized(mMapViewController, this); } } private void unRegisterControllersForAndroidAutoModule() { if (mAndroidAutoModuleInitialized) { - NavAutoModule.getInstance().androidAutoNavigationScreenDisposed(); + GMNNavAutoModule.getInstance().androidAutoNavigationScreenDisposed(); } } @@ -157,7 +152,7 @@ public void onSurfaceAvailable(@NonNull SurfaceContainer surfaceContainer) { mNavigationView.getMapAsync( (GoogleMap googleMap) -> { mGoogleMap = googleMap; - mMapViewController = new MapViewController(); + mMapViewController = new GMNMapViewController(); mMapViewController.initialize(googleMap, () -> null); registerControllersForAndroidAutoModule(); invalidate(); @@ -195,7 +190,7 @@ public void onScale(float focusX, float focusY, float scaleFactor) { } protected void sendCustomEvent(String type, ReadableMap data) { - NavAutoModule.getInstance().onCustomNavigationAutoEvent(type, data); + GMNNavAutoModule.getInstance().onCustomNavigationAutoEvent(type, data); } @NonNull @@ -205,4 +200,7 @@ public Template onGetTemplate() { .setMapActionStrip(new ActionStrip.Builder().addAction(Action.PAN).build()) .build(); } + + @Override + public void setStylingOptions(StylingOptions stylingOptions) {} } diff --git a/android/src/main/java/com/google/maps/android/rn/navsdk/GMNCircle.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNCircle.java new file mode 100644 index 00000000..c303f84f --- /dev/null +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNCircle.java @@ -0,0 +1,23 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.maps.android.rn.navsdk; + +import androidx.annotation.Nullable; +import com.google.android.gms.maps.model.Circle; + +/** Immutable wrapper for a Google Maps Circle and an optional RN ID. */ +public record GMNCircle(Circle circle, @Nullable String rnId) {} diff --git a/android/src/main/java/com/google/android/react/navsdk/CollectionUtil.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNCollectionUtil.java similarity index 84% rename from android/src/main/java/com/google/android/react/navsdk/CollectionUtil.java rename to android/src/main/java/com/google/maps/android/rn/navsdk/GMNCollectionUtil.java index 35a22219..93c81cd6 100644 --- a/android/src/main/java/com/google/android/react/navsdk/CollectionUtil.java +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNCollectionUtil.java @@ -11,12 +11,13 @@ * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.react.navsdk; +package com.google.maps.android.rn.navsdk; import java.util.HashMap; import java.util.Map; +import java.util.Objects; -public class CollectionUtil { +public class GMNCollectionUtil { private static Map mObjectMap = new HashMap<>(); @@ -29,13 +30,14 @@ public static int getInt(String name, Map map, int defaultValue) { public static boolean getBool(String name, Map map, boolean defaultValue) { if (map.containsKey(name) && map.get(name) != null) { - return ((Boolean) map.get(name)).booleanValue(); + return (Boolean) Objects.requireNonNull(map.get(name)); } return defaultValue; } public static String getString(String name, Map map) { - if (map.containsKey(name) && map.get(name) != null) return map.get(name).toString(); + if (map.containsKey(name) && map.get(name) != null) + return Objects.requireNonNull(map.get(name)).toString(); return null; } diff --git a/android/src/main/java/com/google/maps/android/rn/navsdk/GMNColorUtil.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNColorUtil.java new file mode 100644 index 00000000..f6391beb --- /dev/null +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNColorUtil.java @@ -0,0 +1,62 @@ +/** + * Copyright 2023 Google LLC + * + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + *

http://www.apache.org/licenses/LICENSE-2.0 + * + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.maps.android.rn.navsdk; + +import android.graphics.Color; + +public class GMNColorUtil { + public static Color colorFromHexString(String hexString) { + String hexValueString = hexString.replace("#", ""); + int length = hexValueString.length(); + + int r, g, b, a = 255; + + try { + if (length == 3) { // #RGB + r = Integer.parseInt(hexValueString.substring(0, 1), 16) * 17; + g = Integer.parseInt(hexValueString.substring(1, 2), 16) * 17; + b = Integer.parseInt(hexValueString.substring(2, 3), 16) * 17; + } else if (length == 4) { // #RGBA + r = Integer.parseInt(hexValueString.substring(0, 1), 16) * 17; + g = Integer.parseInt(hexValueString.substring(1, 2), 16) * 17; + b = Integer.parseInt(hexValueString.substring(2, 3), 16) * 17; + a = Integer.parseInt(hexValueString.substring(3, 4), 16) * 17; + } else if (length == 6) { // #RRGGBB + r = Integer.parseInt(hexValueString.substring(0, 2), 16); + g = Integer.parseInt(hexValueString.substring(2, 4), 16); + b = Integer.parseInt(hexValueString.substring(4, 6), 16); + } else if (length == 8) { // #RRGGBBAA + r = Integer.parseInt(hexValueString.substring(0, 2), 16); + g = Integer.parseInt(hexValueString.substring(2, 4), 16); + b = Integer.parseInt(hexValueString.substring(4, 6), 16); + a = Integer.parseInt(hexValueString.substring(6, 8), 16); + } else { + throw new IllegalArgumentException("Unsupported color format"); + } + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Invalid color format", e); + } + + return Color.valueOf(r / 255f, g / 255f, b / 255f, a / 255f); + } + + public static String hexStringFromColor(Color color) { + int r = Math.round(color.red() * 255); + int g = Math.round(color.green() * 255); + int b = Math.round(color.blue() * 255); + int a = Math.round(color.alpha() * 255); + + return String.format("#%02X%02X%02X%02X", a, r, g, b); + } +} diff --git a/android/src/main/java/com/google/android/react/navsdk/Constants.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNConstants.java similarity index 75% rename from android/src/main/java/com/google/android/react/navsdk/Constants.java rename to android/src/main/java/com/google/maps/android/rn/navsdk/GMNConstants.java index 0c046b37..bc6500b4 100644 --- a/android/src/main/java/com/google/android/react/navsdk/Constants.java +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNConstants.java @@ -11,11 +11,9 @@ * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.react.navsdk; +package com.google.maps.android.rn.navsdk; -public class Constants { - public static final String NAV_JAVASCRIPT_FLAG = "NavJavascriptBridge"; - public static final String NAV_AUTO_JAVASCRIPT_FLAG = "NavAutoJavascriptBridge"; +public class GMNConstants { public static final String LAT_FIELD_KEY = "lat"; public static final String LNG_FIELD_KEY = "lng"; } diff --git a/android/src/main/java/com/google/android/react/navsdk/CustomTypes.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNCustomTypes.java similarity index 86% rename from android/src/main/java/com/google/android/react/navsdk/CustomTypes.java rename to android/src/main/java/com/google/maps/android/rn/navsdk/GMNCustomTypes.java index 909b8075..f14bbcf1 100644 --- a/android/src/main/java/com/google/android/react/navsdk/CustomTypes.java +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNCustomTypes.java @@ -11,10 +11,10 @@ * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.react.navsdk; +package com.google.maps.android.rn.navsdk; -public class CustomTypes { - public enum FragmentType { +public class GMNCustomTypes { + public enum MapViewType { MAP, NAVIGATION } diff --git a/android/src/main/java/com/google/android/react/navsdk/EnumTranslationUtil.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNEnumTranslationUtil.java similarity index 51% rename from android/src/main/java/com/google/android/react/navsdk/EnumTranslationUtil.java rename to android/src/main/java/com/google/maps/android/rn/navsdk/GMNEnumTranslationUtil.java index b6da0461..68032048 100644 --- a/android/src/main/java/com/google/android/react/navsdk/EnumTranslationUtil.java +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNEnumTranslationUtil.java @@ -11,7 +11,7 @@ * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.react.navsdk; +package com.google.maps.android.rn.navsdk; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.GoogleMap.CameraPerspective; @@ -19,28 +19,21 @@ import com.google.android.libraries.navigation.ForceNightMode; import com.google.android.libraries.navigation.Navigator; -public class EnumTranslationUtil { +public class GMNEnumTranslationUtil { public static AlternateRoutesStrategy getAlternateRoutesStrategyFromJsValue(int jsValue) { - switch (jsValue) { - case 1: - return AlternateRoutesStrategy.SHOW_NONE; - case 2: - return AlternateRoutesStrategy.SHOW_ONE; - default: - return AlternateRoutesStrategy.SHOW_ALL; - } + return switch (jsValue) { + case 1 -> AlternateRoutesStrategy.SHOW_NONE; + case 2 -> AlternateRoutesStrategy.SHOW_ONE; + default -> AlternateRoutesStrategy.SHOW_ALL; + }; } public static @Navigator.AudioGuidance int getAudioGuidanceFromJsValue(int jsValue) { - switch (jsValue) { - case 0: - return Navigator.AudioGuidance.SILENT; - case 1: - return Navigator.AudioGuidance.VOICE_ALERTS_ONLY; - case 2: - default: - return Navigator.AudioGuidance.VOICE_ALERTS_AND_GUIDANCE; - } + return switch (jsValue) { + case 0 -> Navigator.AudioGuidance.SILENT; + case 1 -> Navigator.AudioGuidance.VOICE_ALERTS_ONLY; + default -> Navigator.AudioGuidance.VOICE_ALERTS_AND_GUIDANCE; + }; } public static @Navigator.TaskRemovedBehavior int getTaskRemovedBehaviourFromJsValue(int jsValue) { @@ -52,50 +45,35 @@ public static AlternateRoutesStrategy getAlternateRoutesStrategyFromJsValue(int } public static int getMapTypeFromJsValue(int jsValue) { - switch (jsValue) { - case 1: - return GoogleMap.MAP_TYPE_NORMAL; - case 2: - return GoogleMap.MAP_TYPE_SATELLITE; - case 3: - return GoogleMap.MAP_TYPE_TERRAIN; - case 4: - return GoogleMap.MAP_TYPE_HYBRID; - default: - return GoogleMap.MAP_TYPE_NONE; - } + return switch (jsValue) { + case 1 -> GoogleMap.MAP_TYPE_NORMAL; + case 2 -> GoogleMap.MAP_TYPE_SATELLITE; + case 3 -> GoogleMap.MAP_TYPE_TERRAIN; + case 4 -> GoogleMap.MAP_TYPE_HYBRID; + default -> GoogleMap.MAP_TYPE_NONE; + }; } public static @ForceNightMode int getForceNightModeFromJsValue(int jsValue) { - switch (jsValue) { - case 0: - return ForceNightMode.AUTO; - case 1: - return ForceNightMode.FORCE_DAY; - case 2: - default: - return ForceNightMode.FORCE_NIGHT; - } + return switch (jsValue) { + case 0 -> ForceNightMode.AUTO; + case 1 -> ForceNightMode.FORCE_DAY; + default -> ForceNightMode.FORCE_NIGHT; + }; } public static @CameraPerspective int getCameraPerspectiveFromJsValue(int jsValue) { - switch (jsValue) { - case 1: - return CameraPerspective.TOP_DOWN_NORTH_UP; - case 2: - return CameraPerspective.TOP_DOWN_HEADING_UP; - default: - return CameraPerspective.TILTED; - } + return switch (jsValue) { + case 1 -> CameraPerspective.TOP_DOWN_NORTH_UP; + case 2 -> CameraPerspective.TOP_DOWN_HEADING_UP; + default -> CameraPerspective.TILTED; + }; } - public static CustomTypes.FragmentType getFragmentTypeFromJsValue(int jsValue) { - switch (jsValue) { - case 0: - default: - return CustomTypes.FragmentType.MAP; - case 1: - return CustomTypes.FragmentType.NAVIGATION; - } + public static GMNCustomTypes.MapViewType getMapViewTypeFromJsValue(int jsValue) { + return switch (jsValue) { + default -> GMNCustomTypes.MapViewType.MAP; + case 1 -> GMNCustomTypes.MapViewType.NAVIGATION; + }; } } diff --git a/android/src/main/java/com/google/maps/android/rn/navsdk/GMNGroundOverlay.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNGroundOverlay.java new file mode 100644 index 00000000..f53b1ed3 --- /dev/null +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNGroundOverlay.java @@ -0,0 +1,23 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.maps.android.rn.navsdk; + +import androidx.annotation.Nullable; +import com.google.android.gms.maps.model.GroundOverlay; + +/** Immutable wrapper for a Google Maps GroundOverlay and an optional RN ID. */ +public record GMNGroundOverlay(GroundOverlay groundOverlay, @Nullable String rnId) {} diff --git a/android/src/main/java/com/google/maps/android/rn/navsdk/GMNJsErrors.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNJsErrors.java new file mode 100644 index 00000000..80ab11f7 --- /dev/null +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNJsErrors.java @@ -0,0 +1,41 @@ +/** + * Copyright 2023 Google LLC + * + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + *

http://www.apache.org/licenses/LICENSE-2.0 + * + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.maps.android.rn.navsdk; + +public class GMNJsErrors { + public static final String NO_ACTIVITY_ERROR_CODE = "NO_ACTIVITY_ERROR_CODE"; + public static final String NO_ACTIVITY_ERROR_MESSAGE = + "Activity missing while processing the action"; + public static final String NO_NAVIGATOR_ERROR_CODE = "NO_NAVIGATOR_ERROR_CODE"; + public static final String NO_NAVIGATOR_ERROR_MESSAGE = + "Make sure to initialize the navigator is ready before executing."; + public static final String NO_MAP_ERROR_CODE = "NO_MAP_ERROR_CODE"; + public static final String NO_MAP_ERROR_MESSAGE = + "Map view is not initialized or not found for the provided viewId."; + public static final String VIEW_NOT_FOUND_ERROR_CODE = "VIEW_NOT_FOUND_ERROR_CODE"; + public static final String VIEW_NOT_FOUND_ERROR_MESSAGE = + "View not found for the provided viewId."; + public static final String NO_WAYPOINTS_GUIDANCE_ERROR_CODE = "NO_WAYPOINTS_GUIDANCE_ERROR_CODE"; + public static final String NO_WAYPOINTS_GUIDANCE_ERROR_MESSAGE = + "No waypoints set. Ensure destinations are added before starting guidance."; + public static final String FAILED_TO_CREATE_MAP_OBJECT_ERROR_CODE = + "FAILED_TO_CREATE_MAP_OBJECT_ERROR_CODE"; + public static final String FAILED_TO_CREATE_MAP_OBJECT_ERROR_MESSAGE = + "Error while adding map object to the map."; + public static final String TERMS_NOT_ACCEPTED_ERROR_CODE = "TERMS_NOT_ACCEPTED_ERROR_CODE"; + public static final String TERMS_NOT_ACCEPTED_ERROR_MESSAGE = + "Terms and conditions not accepted."; + + public static final String UNKNOWN_NATIVE_ERROR_CODE = "NATIVE_ERROR_CODE"; +} diff --git a/android/src/main/java/com/google/maps/android/rn/navsdk/GMNJsonUtils.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNJsonUtils.java new file mode 100644 index 00000000..47647e0a --- /dev/null +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNJsonUtils.java @@ -0,0 +1,37 @@ +/** + * Copyright 2023 Google LLC + * + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + *

http://www.apache.org/licenses/LICENSE-2.0 + * + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.maps.android.rn.navsdk; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import java.lang.reflect.Type; +import java.util.HashMap; + +public class GMNJsonUtils { + private static final Gson gson = new Gson(); + private static final Type TYPE = new TypeToken>() {}.getType(); + + /** + * Converts a JSON string to a HashMap. + * + * @param jsonString JSON string to convert + * @return HashMap representation of the JSON + */ + public static HashMap jsonToMap(String jsonString) { + if (jsonString == null || jsonString.trim().isEmpty()) { + return new HashMap<>(); // Return empty map if input is null or empty + } + return gson.fromJson(jsonString, TYPE); + } +} diff --git a/android/src/main/java/com/google/maps/android/rn/navsdk/GMNMapViewController.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNMapViewController.java new file mode 100644 index 00000000..7249b245 --- /dev/null +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNMapViewController.java @@ -0,0 +1,664 @@ +/** + * Copyright 2024 Google LLC + * + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + *

http://www.apache.org/licenses/LICENSE-2.0 + * + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.maps.android.rn.navsdk; + +import android.annotation.SuppressLint; +import android.app.Activity; +import androidx.annotation.Nullable; +import androidx.core.util.Supplier; +import com.facebook.react.bridge.UiThreadUtil; +import com.google.android.gms.maps.CameraUpdateFactory; +import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.maps.model.BitmapDescriptor; +import com.google.android.gms.maps.model.BitmapDescriptorFactory; +import com.google.android.gms.maps.model.CameraPosition; +import com.google.android.gms.maps.model.Circle; +import com.google.android.gms.maps.model.CircleOptions; +import com.google.android.gms.maps.model.GroundOverlay; +import com.google.android.gms.maps.model.GroundOverlayOptions; +import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.MapStyleOptions; +import com.google.android.gms.maps.model.Marker; +import com.google.android.gms.maps.model.MarkerOptions; +import com.google.android.gms.maps.model.Polygon; +import com.google.android.gms.maps.model.PolygonOptions; +import com.google.android.gms.maps.model.Polyline; +import com.google.android.gms.maps.model.PolylineOptions; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executors; + +public class GMNMapViewController { + private GoogleMap mGoogleMap; + private Supplier activitySupplier; + private IGMNMapViewCallback mMapViewCallback; + + // Wrapper storage: key is rnId if present, else Google Maps object id. + private final HashMap markerMap = new HashMap<>(); + private final HashMap polylineMap = new HashMap<>(); + private final HashMap polygonMap = new HashMap<>(); + private final HashMap circleMap = new HashMap<>(); + private final HashMap groundOverlayMap = new HashMap<>(); + + // Google Maps object id -> rnId (or itself if rnId is null). + private final HashMap markerIdToRnId = new HashMap<>(); + private final HashMap polylineIdToRnId = new HashMap<>(); + private final HashMap polygonIdToRnId = new HashMap<>(); + private final HashMap circleIdToRnId = new HashMap<>(); + private final HashMap groundOverlayIdToRnId = new HashMap<>(); + + private String style = ""; + private Float minZoomPreference = null; + private Float maxZoomPreference = null; + + public void initialize(GoogleMap googleMap, Supplier activitySupplier) { + this.mGoogleMap = googleMap; + this.activitySupplier = activitySupplier; + } + + public void setupMapListeners(IGMNMapViewCallback navigationViewCallback) { + this.mMapViewCallback = navigationViewCallback; + if (mGoogleMap == null || mMapViewCallback == null) return; + + mGoogleMap.setOnMarkerClickListener( + marker -> { + String key = markerIdToRnId.getOrDefault(marker.getId(), marker.getId()); + GMNMarker gmnMarker = markerMap.get(key); + if (gmnMarker != null) { + mMapViewCallback.onMarkerClick(gmnMarker); + } + return false; + }); + + mGoogleMap.setOnPolylineClickListener( + polyline -> { + String key = polylineIdToRnId.getOrDefault(polyline.getId(), polyline.getId()); + GMNPolyline gmnPolyline = polylineMap.get(key); + if (gmnPolyline != null) { + mMapViewCallback.onPolylineClick(gmnPolyline); + } + }); + + mGoogleMap.setOnPolygonClickListener( + polygon -> { + String key = polygonIdToRnId.getOrDefault(polygon.getId(), polygon.getId()); + GMNPolygon gmnPolygon = polygonMap.get(key); + if (gmnPolygon != null) { + mMapViewCallback.onPolygonClick(gmnPolygon); + } + }); + + mGoogleMap.setOnCircleClickListener( + circle -> { + String key = circleIdToRnId.getOrDefault(circle.getId(), circle.getId()); + GMNCircle gmnCircle = circleMap.get(key); + if (gmnCircle != null) { + mMapViewCallback.onCircleClick(gmnCircle); + } + }); + + mGoogleMap.setOnGroundOverlayClickListener( + groundOverlay -> { + String key = + groundOverlayIdToRnId.getOrDefault(groundOverlay.getId(), groundOverlay.getId()); + GMNGroundOverlay gmnGroundOverlay = groundOverlayMap.get(key); + if (gmnGroundOverlay != null) { + mMapViewCallback.onGroundOverlayClick(gmnGroundOverlay); + } + }); + + mGoogleMap.setOnInfoWindowClickListener( + marker -> { + String key = markerIdToRnId.getOrDefault(marker.getId(), marker.getId()); + GMNMarker gmnMarker = markerMap.get(key); + if (gmnMarker != null) { + mMapViewCallback.onMarkerInfoWindowTapped(gmnMarker); + } + }); + + mGoogleMap.setOnMapClickListener(latLng -> mMapViewCallback.onMapClick(latLng)); + } + + public GoogleMap getGoogleMap() { + return mGoogleMap; + } + + @Nullable + public GMNCircle addCircle(Map optionsMap) { + if (mGoogleMap == null) { + return null; + } + + CircleOptions options = new CircleOptions(); + + float strokeWidth = + Double.valueOf(GMNCollectionUtil.getDouble("strokeWidth", optionsMap, 0)).floatValue(); + options.strokeWidth(strokeWidth); + + double radius = GMNCollectionUtil.getDouble("radius", optionsMap, 0.0); + options.radius(radius); + + boolean visible = GMNCollectionUtil.getBool("visible", optionsMap, true); + options.visible(visible); + + Object centerObj = optionsMap.get("center"); + if (centerObj instanceof Map) { + @SuppressWarnings("unchecked") + Map centerMap = (Map) centerObj; + options.center(GMNObjectTranslationUtil.getLatLngFromMap(centerMap)); + } + + boolean clickable = GMNCollectionUtil.getBool("clickable", optionsMap, false); + options.clickable(clickable); + + String strokeColor = GMNCollectionUtil.getString("strokeColor", optionsMap); + if (strokeColor != null) { + options.strokeColor(GMNColorUtil.colorFromHexString(strokeColor).toArgb()); + } + + String fillColor = GMNCollectionUtil.getString("fillColor", optionsMap); + if (fillColor != null) { + options.fillColor(GMNColorUtil.colorFromHexString(fillColor).toArgb()); + } + + Circle circle = mGoogleMap.addCircle(options); + String rnId = GMNCollectionUtil.getString("id", optionsMap); + GMNCircle gmnCircle = new GMNCircle(circle, rnId); + String key = rnId != null ? rnId : circle.getId(); + circleMap.put(key, gmnCircle); + circleIdToRnId.put(circle.getId(), key); + return gmnCircle; + } + + @Nullable + public GMNMarker addMarker(Map optionsMap) { + if (mGoogleMap == null) { + return null; + } + + String imagePath = GMNCollectionUtil.getString("imgPath", optionsMap); + String title = GMNCollectionUtil.getString("title", optionsMap); + String snippet = GMNCollectionUtil.getString("snippet", optionsMap); + float alpha = Double.valueOf(GMNCollectionUtil.getDouble("alpha", optionsMap, 1)).floatValue(); + float rotation = + Double.valueOf(GMNCollectionUtil.getDouble("rotation", optionsMap, 0)).floatValue(); + boolean draggable = GMNCollectionUtil.getBool("draggable", optionsMap, false); + boolean flat = GMNCollectionUtil.getBool("flat", optionsMap, false); + boolean visible = GMNCollectionUtil.getBool("visible", optionsMap, true); + + MarkerOptions options = new MarkerOptions(); + if (imagePath != null && !imagePath.isEmpty()) { + BitmapDescriptor icon = BitmapDescriptorFactory.fromAsset(imagePath); + options.icon(icon); + } + + Object positionObj = optionsMap.get("position"); + if (positionObj instanceof Map) { + @SuppressWarnings("unchecked") + Map positionMap = (Map) positionObj; + LatLng latLng = GMNObjectTranslationUtil.getLatLngFromMap(positionMap); + if (latLng != null) { + options.position(latLng); + } + } + + if (title != null) { + options.title(title); + } + + if (snippet != null) { + options.snippet(snippet); + } + + options.flat(flat); + options.alpha(alpha); + options.rotation(rotation); + options.draggable(draggable); + options.visible(visible); + + Marker marker = mGoogleMap.addMarker(options); + String rnId = GMNCollectionUtil.getString("id", optionsMap); + GMNMarker gmnMarker = new GMNMarker(marker, rnId); + String key = rnId != null ? rnId : marker.getId(); + markerMap.put(key, gmnMarker); + markerIdToRnId.put(marker.getId(), key); + return gmnMarker; + } + + @Nullable + public GMNPolyline addPolyline(Map optionsMap) { + if (mGoogleMap == null) { + return null; + } + + float width = Double.valueOf(GMNCollectionUtil.getDouble("width", optionsMap, 0)).floatValue(); + boolean clickable = GMNCollectionUtil.getBool("clickable", optionsMap, false); + boolean visible = GMNCollectionUtil.getBool("visible", optionsMap, true); + + Object pointsObj = optionsMap.get("points"); + if (!(pointsObj instanceof List)) { + return null; + } + + @SuppressWarnings("unchecked") + List> latLngList = (List>) pointsObj; + + PolylineOptions options = new PolylineOptions(); + for (Map latLngMap : latLngList) { + options.add(createLatLng(latLngMap)); + } + + String color = GMNCollectionUtil.getString("color", optionsMap); + if (color != null) { + options.color(GMNColorUtil.colorFromHexString(color).toArgb()); + } + + options.width(width); + options.clickable(clickable); + options.visible(visible); + + Polyline polyline = mGoogleMap.addPolyline(options); + String rnId = GMNCollectionUtil.getString("id", optionsMap); + GMNPolyline gmnPolyline = new GMNPolyline(polyline, rnId); + String key = rnId != null ? rnId : polyline.getId(); + polylineMap.put(key, gmnPolyline); + polylineIdToRnId.put(polyline.getId(), key); + return gmnPolyline; + } + + @Nullable + public GMNPolygon addPolygon(Map optionsMap) { + if (mGoogleMap == null) { + return null; + } + + String strokeColor = GMNCollectionUtil.getString("strokeColor", optionsMap); + String fillColor = GMNCollectionUtil.getString("fillColor", optionsMap); + float strokeWidth = + Double.valueOf(GMNCollectionUtil.getDouble("strokeWidth", optionsMap, 0)).floatValue(); + boolean clickable = GMNCollectionUtil.getBool("clickable", optionsMap, false); + boolean geodesic = GMNCollectionUtil.getBool("geodesic", optionsMap, false); + boolean visible = GMNCollectionUtil.getBool("visible", optionsMap, true); + + Object pointsObj = optionsMap.get("points"); + if (!(pointsObj instanceof List)) { + return null; + } + + @SuppressWarnings("unchecked") + List> latLngList = (List>) pointsObj; + + PolygonOptions options = new PolygonOptions(); + for (Map latLngMap : latLngList) { + options.add(createLatLng(latLngMap)); + } + + Object holesObj = optionsMap.get("holes"); + if (holesObj instanceof List) { + @SuppressWarnings("unchecked") + List>> holesArr = (List>>) holesObj; + + for (List> hole : holesArr) { + List listHoles = new ArrayList<>(); + for (Map latLngMap : hole) { + listHoles.add(createLatLng(latLngMap)); + } + if (!listHoles.isEmpty()) { + options.addHole(listHoles); + } + } + } + + if (fillColor != null) { + options.fillColor(GMNColorUtil.colorFromHexString(fillColor).toArgb()); + } + + if (strokeColor != null) { + options.strokeColor(GMNColorUtil.colorFromHexString(strokeColor).toArgb()); + } + + options.strokeWidth(strokeWidth); + options.visible(visible); + options.geodesic(geodesic); + options.clickable(clickable); + + Polygon polygon = mGoogleMap.addPolygon(options); + String rnId = GMNCollectionUtil.getString("id", optionsMap); + GMNPolygon gmnPolygon = new GMNPolygon(polygon, rnId); + String key = rnId != null ? rnId : polygon.getId(); + polygonMap.put(key, gmnPolygon); + polygonIdToRnId.put(polygon.getId(), key); + + return gmnPolygon; + } + + @Nullable + public GMNGroundOverlay addGroundOverlay(Map optionsMap) { + if (mGoogleMap == null) { + return null; + } + + String imagePath = GMNCollectionUtil.getString("imgPath", optionsMap); + float width = Double.valueOf(GMNCollectionUtil.getDouble("width", optionsMap, 0)).floatValue(); + float height = + Double.valueOf(GMNCollectionUtil.getDouble("height", optionsMap, 0)).floatValue(); + float transparency = + Double.valueOf(1.0 - GMNCollectionUtil.getDouble("alpha", optionsMap, 1)).floatValue(); + boolean clickable = GMNCollectionUtil.getBool("clickable", optionsMap, false); + boolean visible = GMNCollectionUtil.getBool("visible", optionsMap, true); + + LatLng location = null; + Object locationObj = optionsMap.get("location"); + if (locationObj instanceof Map) { + @SuppressWarnings("unchecked") + Map latlngMap = (Map) locationObj; + double lat = GMNCollectionUtil.getDouble("lat", latlngMap, 0); + double lng = GMNCollectionUtil.getDouble("lng", latlngMap, 0); + location = new LatLng(lat, lng); + } + + if (location == null) { + return null; // Cannot add overlay without a valid position + } + + GroundOverlayOptions options = new GroundOverlayOptions(); + if (imagePath != null && !imagePath.isEmpty()) { + BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromAsset(imagePath); + options.image(bitmapDescriptor); + } + options.position(location, width, height); + options.transparency(transparency); + options.clickable(clickable); + options.visible(visible); + GroundOverlay groundOverlay = mGoogleMap.addGroundOverlay(options); + String rnId = GMNCollectionUtil.getString("id", optionsMap); + GMNGroundOverlay gmnGroundOverlay = new GMNGroundOverlay(groundOverlay, rnId); + String key = rnId != null ? rnId : groundOverlay.getId(); + groundOverlayMap.put(key, gmnGroundOverlay); + groundOverlayIdToRnId.put(groundOverlay.getId(), key); + + return gmnGroundOverlay; + } + + public void removeMarker(String id) { + GMNMarker m = markerMap.remove(id); + if (m != null) { + markerIdToRnId.remove(m.marker().getId()); + m.marker().remove(); + } + } + + public void removePolyline(String id) { + GMNPolyline p = polylineMap.remove(id); + if (p != null) { + polylineIdToRnId.remove(p.polyline().getId()); + p.polyline().remove(); + } + } + + public void removePolygon(String id) { + GMNPolygon p = polygonMap.remove(id); + if (p != null) { + polygonIdToRnId.remove(p.polygon().getId()); + p.polygon().remove(); + } + } + + public void removeCircle(String id) { + GMNCircle c = circleMap.remove(id); + if (c != null) { + circleIdToRnId.remove(c.circle().getId()); + c.circle().remove(); + } + } + + public void removeGroundOverlay(String id) { + GMNGroundOverlay g = groundOverlayMap.remove(id); + if (g != null) { + groundOverlayIdToRnId.remove(g.groundOverlay().getId()); + g.groundOverlay().remove(); + } + } + + public void setMapStyle(String url) { + Executors.newSingleThreadExecutor() + .execute( + () -> { + try { + style = fetchJsonFromUrl(url); + } catch (IOException e) { + throw new RuntimeException(e); + } + + Activity activity = activitySupplier.get(); + if (activity != null) { + activity.runOnUiThread( + () -> { + MapStyleOptions options = new MapStyleOptions(style); + mGoogleMap.setMapStyle(options); + }); + } + }); + } + + /** Moves the position of the camera to hover over Melbourne. */ + public void moveCamera(CameraPosition cameraPosition) { + mGoogleMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); + } + + public void animateCamera(CameraPosition cameraPosition, int animationDuration) { + if (mGoogleMap != null) { + mGoogleMap.animateCamera( + CameraUpdateFactory.newCameraPosition(cameraPosition), animationDuration, null); + } + } + + public void setZoomLevel(int level) { + if (mGoogleMap != null) { + mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(level)); + } + } + + public void setIndoorEnabled(boolean isOn) { + if (mGoogleMap != null) { + mGoogleMap.setIndoorEnabled(isOn); + } + } + + public void setTrafficEnabled(boolean isOn) { + if (mGoogleMap != null) { + mGoogleMap.setTrafficEnabled(isOn); + } + } + + public void setCompassEnabled(boolean isOn) { + if (mGoogleMap != null) { + mGoogleMap.getUiSettings().setCompassEnabled(isOn); + } + } + + public void setRotateGesturesEnabled(boolean isOn) { + if (mGoogleMap != null) { + mGoogleMap.getUiSettings().setRotateGesturesEnabled(isOn); + } + } + + public void setScrollGesturesEnabled(boolean isOn) { + if (mGoogleMap != null) { + mGoogleMap.getUiSettings().setScrollGesturesEnabled(isOn); + } + } + + public void setScrollGesturesEnabledDuringRotateOrZoom(boolean isOn) { + if (mGoogleMap != null) { + mGoogleMap.getUiSettings().setScrollGesturesEnabledDuringRotateOrZoom(isOn); + } + } + + public void setTiltGesturesEnabled(boolean isOn) { + if (mGoogleMap != null) { + mGoogleMap.getUiSettings().setTiltGesturesEnabled(isOn); + } + } + + public void setZoomControlsEnabled(boolean isOn) { + if (mGoogleMap != null) { + mGoogleMap.getUiSettings().setZoomControlsEnabled(isOn); + } + } + + public void setZoomGesturesEnabled(boolean isOn) { + if (mGoogleMap != null) { + mGoogleMap.getUiSettings().setZoomGesturesEnabled(isOn); + } + } + + public void setBuildingsEnabled(boolean isOn) { + if (mGoogleMap != null) { + mGoogleMap.setBuildingsEnabled(isOn); + } + } + + @SuppressLint("MissingPermission") + public void setMyLocationEnabled(boolean isOn) { + if (mGoogleMap != null) { + mGoogleMap.setMyLocationEnabled(isOn); + } + } + + public void setMapToolbarEnabled(boolean isOn) { + if (mGoogleMap != null) { + mGoogleMap.getUiSettings().setMapToolbarEnabled(isOn); + } + } + + /** Toggles whether the location marker is enabled. */ + public void setMyLocationButtonEnabled(boolean isOn) { + if (mGoogleMap == null) { + return; + } + + UiThreadUtil.runOnUiThread( + () -> { + mGoogleMap.getUiSettings().setMyLocationButtonEnabled(isOn); + }); + } + + public void setMapType(int jsValue) { + if (mGoogleMap == null) { + return; + } + + mGoogleMap.setMapType(GMNEnumTranslationUtil.getMapTypeFromJsValue(jsValue)); + } + + public void clearMapView() { + if (mGoogleMap == null) { + return; + } + mGoogleMap.clear(); + markerMap.clear(); + polylineMap.clear(); + polygonMap.clear(); + circleMap.clear(); + groundOverlayMap.clear(); + markerIdToRnId.clear(); + polylineIdToRnId.clear(); + polygonIdToRnId.clear(); + circleIdToRnId.clear(); + groundOverlayIdToRnId.clear(); + } + + @SuppressLint("MissingPermission") + public void setFollowingPerspective(int jsValue) { + if (mGoogleMap == null) { + return; + } + + mGoogleMap.followMyLocation(GMNEnumTranslationUtil.getCameraPerspectiveFromJsValue(jsValue)); + } + + public void setPadding(int left, int top, int right, int bottom) { + if (mGoogleMap != null) { + mGoogleMap.setPadding(left, top, right, bottom); + } + } + + private String fetchJsonFromUrl(String urlString) throws IOException { + URL url = new URL(urlString); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + + int responseCode = connection.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { + InputStream inputStream = connection.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); + StringBuilder stringBuilder = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + stringBuilder.append(line); + } + reader.close(); + inputStream.close(); + return stringBuilder.toString(); + } else { + // Handle error response + throw new IOException("Error response: " + responseCode); + } + } + + private LatLng createLatLng(Map map) { + Double lat = null; + Double lng = null; + if (map.containsKey("lat") && map.containsKey("lng")) { + if (map.get("lat") != null) lat = Double.parseDouble(map.get("lat").toString()); + if (map.get("lng") != null) lng = Double.parseDouble(map.get("lng").toString()); + } + + return new LatLng(lat, lng); + } + + public void setMinZoomPreference(Float value) { + minZoomPreference = value; + updateMinMaxZoomPreference(); + } + + public void setMaxZoomPreference(Float value) { + maxZoomPreference = value; + updateMinMaxZoomPreference(); + } + + private void updateMinMaxZoomPreference() { + if (mGoogleMap == null) { + return; + } + if (minZoomPreference == null || maxZoomPreference == null) { + mGoogleMap.resetMinMaxZoomPreference(); + } + if (minZoomPreference != null) { + mGoogleMap.setMinZoomPreference(minZoomPreference); + } + if (maxZoomPreference != null) { + mGoogleMap.setMinZoomPreference(maxZoomPreference); + } + } +} diff --git a/android/src/main/java/com/google/android/react/navsdk/MapViewFragment.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNMapViewFragment.java similarity index 57% rename from android/src/main/java/com/google/android/react/navsdk/MapViewFragment.java rename to android/src/main/java/com/google/maps/android/rn/navsdk/GMNMapViewFragment.java index 048699df..3ec933ec 100644 --- a/android/src/main/java/com/google/android/react/navsdk/MapViewFragment.java +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNMapViewFragment.java @@ -11,7 +11,7 @@ * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.react.navsdk; +package com.google.maps.android.rn.navsdk; import android.annotation.SuppressLint; import android.os.Bundle; @@ -19,7 +19,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.WritableMap; import com.facebook.react.uimanager.UIManagerHelper; import com.facebook.react.uimanager.events.Event; @@ -27,43 +27,29 @@ import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.OnMapReadyCallback; import com.google.android.gms.maps.SupportMapFragment; -import com.google.android.gms.maps.model.Circle; -import com.google.android.gms.maps.model.GroundOverlay; import com.google.android.gms.maps.model.LatLng; -import com.google.android.gms.maps.model.Marker; -import com.google.android.gms.maps.model.Polygon; -import com.google.android.gms.maps.model.Polyline; import com.google.android.libraries.navigation.StylingOptions; -import java.util.ArrayList; -import java.util.List; /** * A fragment that displays a view with a Google Map using MapFragment. This fragment's lifecycle is * managed by NavViewManager. */ @SuppressLint("ValidFragment") -public class MapViewFragment extends SupportMapFragment - implements IMapViewFragment, INavigationViewCallback { +public class GMNMapViewFragment extends SupportMapFragment + implements IGMNMapViewFragment, IGMNMapViewCallback { private static final String TAG = "MapViewFragment"; private GoogleMap mGoogleMap; - private MapViewController mMapViewController; - private StylingOptions mStylingOptions; - - private List markerList = new ArrayList<>(); - private List polylineList = new ArrayList<>(); - private List polygonList = new ArrayList<>(); - private List groundOverlayList = new ArrayList<>(); - private List circleList = new ArrayList<>(); - private int viewTag; // React native view tag. - private ReactApplicationContext reactContext; - - public MapViewFragment(ReactApplicationContext reactContext, int viewTag) { + private GMNMapViewController mMapViewController; + + private final int viewId; // React native view tag. + private final ReactContext reactContext; + + public GMNMapViewFragment(ReactContext reactContext, int viewId) { this.reactContext = reactContext; - this.viewTag = viewTag; + this.viewId = viewId; } - ; - private String style = ""; + private @Nullable Runnable mMapReadyListener; @SuppressLint("MissingPermission") @Override @@ -75,63 +61,70 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat public void onMapReady(GoogleMap googleMap) { mGoogleMap = googleMap; - mMapViewController = new MapViewController(); + mMapViewController = new GMNMapViewController(); mMapViewController.initialize(googleMap, () -> requireActivity()); // Setup map listeners with the provided callback - mMapViewController.setupMapListeners(MapViewFragment.this); + mMapViewController.setupMapListeners(GMNMapViewFragment.this); - emitEvent("onMapReady", null); + GMNMapViewFragment.this.onMapReady(); } }); } @Override - public void onMapReady() { - emitEvent("onMapReady", null); + public void setMapReadyListener(Runnable listener) { + this.mMapReadyListener = listener; + if (mGoogleMap != null) { + listener.run(); + } } @Override - public void onRecenterButtonClick() { - emitEvent("onRecenterButtonClick", null); + public void onMapReady() { + if (mMapReadyListener != null) { + mMapReadyListener.run(); + } + emitEvent("onMapReady", null); } @Override - public void onMarkerClick(Marker marker) { - emitEvent("onMarkerClick", ObjectTranslationUtil.getMapFromMarker(marker)); + public void onMarkerClick(GMNMarker marker) { + emitEvent("onMarkerClick", GMNObjectTranslationUtil.getMapFromMarker(marker)); } @Override - public void onPolylineClick(Polyline polyline) { - emitEvent("onPolylineClick", ObjectTranslationUtil.getMapFromPolyline(polyline)); + public void onPolylineClick(GMNPolyline polyline) { + emitEvent("onPolylineClick", GMNObjectTranslationUtil.getMapFromPolyline(polyline)); } @Override - public void onPolygonClick(Polygon polygon) { - emitEvent("onPolygonClick", ObjectTranslationUtil.getMapFromPolygon(polygon)); + public void onPolygonClick(GMNPolygon polygon) { + emitEvent("onPolygonClick", GMNObjectTranslationUtil.getMapFromPolygon(polygon)); } @Override - public void onCircleClick(Circle circle) { - emitEvent("onCircleClick", ObjectTranslationUtil.getMapFromCircle(circle)); + public void onCircleClick(GMNCircle circle) { + emitEvent("onCircleClick", GMNObjectTranslationUtil.getMapFromCircle(circle)); } @Override - public void onGroundOverlayClick(GroundOverlay groundOverlay) { - emitEvent("onGroundOverlayClick", ObjectTranslationUtil.getMapFromGroundOverlay(groundOverlay)); + public void onGroundOverlayClick(GMNGroundOverlay groundOverlay) { + emitEvent( + "onGroundOverlayClick", GMNObjectTranslationUtil.getMapFromGroundOverlay(groundOverlay)); } @Override - public void onMarkerInfoWindowTapped(Marker marker) { - emitEvent("onMarkerInfoWindowTapped", ObjectTranslationUtil.getMapFromMarker(marker)); + public void onMarkerInfoWindowTapped(GMNMarker marker) { + emitEvent("onMarkerInfoWindowTapped", GMNObjectTranslationUtil.getMapFromMarker(marker)); } @Override public void onMapClick(LatLng latLng) { - emitEvent("onMapClick", ObjectTranslationUtil.getMapFromLatLng(latLng)); + emitEvent("onMapClick", GMNObjectTranslationUtil.getMapFromLatLng(latLng)); } - public MapViewController getMapController() { + public GMNMapViewController getMapController() { return mMapViewController; } @@ -147,14 +140,33 @@ public GoogleMap getGoogleMap() { return mGoogleMap; } + @Override + public void onMeasure(int measuredWidth, int measuredHeight) { + View view = getView(); + if (view != null) { + view.measure( + View.MeasureSpec.makeMeasureSpec(measuredWidth, View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(measuredHeight, View.MeasureSpec.EXACTLY)); + view.requestLayout(); + } + } + + @Override + public void onLayout(int width, int height) { + View view = getView(); + if (view != null) { + view.layout(0, 0, width, height); + } + } + private void emitEvent(String eventName, @Nullable WritableMap data) { if (reactContext != null) { EventDispatcher dispatcher = - UIManagerHelper.getEventDispatcherForReactTag(reactContext, viewTag); + UIManagerHelper.getEventDispatcherForReactTag(reactContext, viewId); if (dispatcher != null) { int surfaceId = UIManagerHelper.getSurfaceId(reactContext); - dispatcher.dispatchEvent(new NavViewEvent(surfaceId, viewTag, eventName, data)); + dispatcher.dispatchEvent(new NavViewEvent(surfaceId, viewId, eventName, data)); } } } @@ -164,8 +176,8 @@ public static class NavViewEvent extends Event { private final @Nullable WritableMap eventData; public NavViewEvent( - int surfaceId, int viewTag, String eventName, @Nullable WritableMap eventData) { - super(surfaceId, viewTag); + int surfaceId, int viewId, String eventName, @Nullable WritableMap eventData) { + super(surfaceId, viewId); this.eventName = eventName; this.eventData = eventData; } diff --git a/android/src/main/java/com/google/maps/android/rn/navsdk/GMNMapViewLayout.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNMapViewLayout.java new file mode 100644 index 00000000..79289f59 --- /dev/null +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNMapViewLayout.java @@ -0,0 +1,624 @@ +/** + * Copyright 2023 Google LLC + * + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + *

http://www.apache.org/licenses/LICENSE-2.0 + * + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.maps.android.rn.navsdk; + +import android.annotation.SuppressLint; +import android.os.Bundle; +import android.util.Log; +import android.view.Choreographer; +import android.widget.FrameLayout; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.uimanager.ThemedReactContext; +import com.google.android.gms.maps.model.CameraPosition; + +@SuppressLint("ViewConstructor") +public class GMNMapViewLayout extends FrameLayout { + static final String TAG = "GMNMapViewLayout"; + + private @Nullable IGMNMapViewFragment mFragment; + + private final ThemedReactContext reactContext; + private Integer mNativeID = null; + private boolean mIsFragmentRegistered = false; + private GMNViewProps mInitialViewProps; + + private GMNCustomTypes.MapViewType mMapViewType; + + private boolean mIsMapReady = false; + private boolean mLayoutLoopRunning = false; + private Choreographer.FrameCallback mFrameCallback; + + public GMNMapViewLayout(@NonNull ThemedReactContext context) { + super(context); + mInitialViewProps = new GMNViewProps(); + this.reactContext = context; + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + stopLayoutLoop(); + } + + private void maybeInitFragment() { + if (mFragment == null + && mMapViewType != null + && mInitialViewProps != null + && mInitialViewProps.hasPropsSetForViewInitialization()) { + initFragment(); + } + } + + public void initFragment() { + assert mInitialViewProps != null; + + if (mFragment != null) { + Log.w(TAG, "Attempted to initialize fragment multiple times!"); + return; + } + + Fragment fragment; + if (mMapViewType == GMNCustomTypes.MapViewType.MAP) { + fragment = new GMNMapViewFragment(reactContext, getId()); + } else { + fragment = new GMNNavViewFragment(reactContext, getId()); + } + + Bundle arguments = new Bundle(); + arguments.putParcelable("MapOptions", mInitialViewProps.buildMapOptions()); + fragment.setArguments(arguments); + + mFragment = (IGMNMapViewFragment) fragment; + mFragment.setMapReadyListener( + () -> { + mIsMapReady = true; + + // Install custom invalidator for the map view. + // installInvalidator(); + + // Apply initial props for the view. + applyInitialProps(); + + // After view is added update fragment layout. + startLayoutLoop(); + }); + + post( + () -> { + int viewId = getId(); + FragmentActivity activity = (FragmentActivity) reactContext.getCurrentActivity(); + if (activity != null) { + activity + .getSupportFragmentManager() + .beginTransaction() + .replace(viewId, fragment, String.valueOf(viewId)) + .commit(); + } + maybeRegisterFragment(); + }); + } + + public void setNativeID(int value) { + if (this.mNativeID == null) { + this.mNativeID = value; + maybeRegisterFragment(); + } else { + Log.w(TAG, "Attempted to change nativeID after initialization!"); + } + } + + public void maybeRegisterFragment() { + if (!mIsFragmentRegistered && mNativeID != null && mFragment != null) { + GMNNavViewManager.getInstance().registerFragment(mNativeID, mFragment); + mIsFragmentRegistered = true; + } + } + + public Integer getNativeID() { + return mNativeID; + } + + public IGMNMapViewFragment getFragment() { + return mFragment; + } + + public GMNMapViewController getMapController() { + assert mFragment != null; + return mFragment.getMapController(); + } + + private boolean isReady() { + return mFragment != null && mIsMapReady; + } + + private IGMNNavViewFragment getNavFragment() { + if (mFragment instanceof IGMNNavViewFragment) { + return (IGMNNavViewFragment) mFragment; + } + Log.w(TAG, "Attempting to access Nav specific property on a Map view"); + return null; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + updateFragmentMeasures(); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + updateFragmentLayout(); + } + + // Measure the fragment's view to fit within this GMNMapViewLayout. + // These dimensions (getMeasuredWidth(), getMeasuredHeight()) are determined + // by React Native's Fabric layout pass for GMNMapViewLayout. + private void updateFragmentMeasures() { + if (mFragment != null) { + mFragment.onMeasure(getMeasuredWidth(), getMeasuredHeight()); + } + } + + // Layout the fragment's view to fill this GMNMapViewLayout. + private void updateFragmentLayout() { + if (mFragment != null) { + mFragment.onLayout(getWidth(), getHeight()); + } + } + + // Applies the initial props to the map view after it is ready. + // Note: Some props are passed to the map view via GoogleMapsOptions before it is ready, + // but are also updated here to ensure the map view is in a consistent state. + private void applyInitialProps() { + if (mInitialViewProps == null) return; + + // Apply all props after map is ready + if (mInitialViewProps.navigationUIEnabled != null) { + setNavigationUIEnabled(mInitialViewProps.navigationUIEnabled); + } + + if (mInitialViewProps.mapType != null) { + setMapType(mInitialViewProps.mapType); + } + + setMapPadding(mInitialViewProps.mapPadding); + + if (mInitialViewProps.tripProgressBarEnabled != null) { + setTripProgressBarEnabled(mInitialViewProps.tripProgressBarEnabled); + } + if (mInitialViewProps.trafficIncidentsCardEnabled != null) { + setTrafficIncidentsCardEnabled(mInitialViewProps.trafficIncidentsCardEnabled); + } + if (mInitialViewProps.headerEnabled != null) { + setHeaderEnabled(mInitialViewProps.headerEnabled); + } + if (mInitialViewProps.footerEnabled != null) { + setFooterEnabled(mInitialViewProps.footerEnabled); + } + if (mInitialViewProps.speedometerEnabled != null) { + setSpeedometerEnabled(mInitialViewProps.speedometerEnabled); + } + if (mInitialViewProps.speedLimitIconEnabled != null) { + setSpeedLimitIconEnabled(mInitialViewProps.speedLimitIconEnabled); + } + if (mInitialViewProps.recenterButtonEnabled != null) { + setRecenterButtonEnabled(mInitialViewProps.recenterButtonEnabled); + } + if (mInitialViewProps.navigationViewStylingOptions != null) { + setNavigationViewStylingOptions(mInitialViewProps.navigationViewStylingOptions); + } + if (mInitialViewProps.nightMode != null) { + setNightMode(mInitialViewProps.nightMode); + } + if (mInitialViewProps.followingPerspective != null) { + setFollowingPerspective(mInitialViewProps.followingPerspective); + } + if (mInitialViewProps.mapStyle != null) { + setMapStyle(mInitialViewProps.mapStyle); + } + if (mInitialViewProps.mapToolbarEnabled != null) { + setMapToolbarEnabled(mInitialViewProps.mapToolbarEnabled); + } + if (mInitialViewProps.indoorEnabled != null) { + setIndoorEnabled(mInitialViewProps.indoorEnabled); + } + if (mInitialViewProps.trafficEnabled != null) { + setTrafficEnabled(mInitialViewProps.trafficEnabled); + } + if (mInitialViewProps.compassEnabled != null) { + setCompassEnabled(mInitialViewProps.compassEnabled); + } + if (mInitialViewProps.myLocationButtonEnabled != null) { + setMyLocationButtonEnabled(mInitialViewProps.myLocationButtonEnabled); + } + if (mInitialViewProps.myLocationEnabled != null) { + setMyLocationEnabled(mInitialViewProps.myLocationEnabled); + } + if (mInitialViewProps.rotateGesturesEnabled != null) { + setRotateGesturesEnabled(mInitialViewProps.rotateGesturesEnabled); + } + if (mInitialViewProps.scrollGesturesEnabled != null) { + setScrollGesturesEnabled(mInitialViewProps.scrollGesturesEnabled); + } + if (mInitialViewProps.scrollGesturesEnabledDuringRotateOrZoom != null) { + setScrollGesturesEnabledDuringRotateOrZoom( + mInitialViewProps.scrollGesturesEnabledDuringRotateOrZoom); + } + if (mInitialViewProps.tiltGesturesEnabled != null) { + setTiltGesturesEnabled(mInitialViewProps.tiltGesturesEnabled); + } + if (mInitialViewProps.zoomControlsEnabled != null) { + setZoomControlsEnabled(mInitialViewProps.zoomControlsEnabled); + } + if (mInitialViewProps.zoomGesturesEnabled != null) { + setZoomGesturesEnabled(mInitialViewProps.zoomGesturesEnabled); + } + if (mInitialViewProps.buildingsEnabled != null) { + setBuildingsEnabled(mInitialViewProps.buildingsEnabled); + } + if (mInitialViewProps.maxZoomPreference != null) { + setMinZoomLevel(mInitialViewProps.maxZoomPreference); + } + if (mInitialViewProps.minZoomPreference != null) { + setMaxZoomLevel(mInitialViewProps.minZoomPreference); + } + if (mInitialViewProps.initialCameraPosition != null) { + setInitialCameraPosition(mInitialViewProps.initialCameraPosition); + } + + // Clear props after applying + mInitialViewProps = null; + } + + // --- Prop Setters --- + public void setMapViewType(GMNCustomTypes.MapViewType mapViewType) { + mMapViewType = mapViewType; + maybeInitFragment(); + } + + public void setNavigationUIEnabled(@Nullable Boolean value) { + if (isReady() && value != null) { + IGMNNavViewFragment navFragment = getNavFragment(); + if (navFragment != null) { + navFragment.setNavigationUiEnabled(value); + } + } else if (mInitialViewProps != null) mInitialViewProps.navigationUIEnabled = value; + } + + public void setMapType(int value) { + if (isReady()) { + getMapController().setMapType(value); + } else if (mInitialViewProps != null) { + mInitialViewProps.initialMapTypeSet = true; + mInitialViewProps.mapType = value; + maybeInitFragment(); + } + } + + public void setMapPadding(@Nullable ReadableMap value) { + if (isReady()) { + if (value != null) { + getMapController() + .setPadding( + (int) value.getDouble("left"), + (int) value.getDouble("top"), + (int) value.getDouble("right"), + (int) value.getDouble("bottom")); + } else { + getMapController().setPadding(0, 0, 0, 0); + } + } else if (mInitialViewProps != null) mInitialViewProps.mapPadding = value; + } + + public void setTripProgressBarEnabled(boolean value) { + if (isReady()) { + IGMNNavViewFragment navFragment = getNavFragment(); + if (navFragment != null) { + navFragment.setTripProgressBarEnabled(value); + } + } else if (mInitialViewProps != null) mInitialViewProps.tripProgressBarEnabled = value; + } + + public void setTrafficIncidentsCardEnabled(boolean value) { + if (isReady()) { + IGMNNavViewFragment navFragment = getNavFragment(); + if (navFragment != null) { + navFragment.setTrafficIncidentCardsEnabled(value); + } + } else if (mInitialViewProps != null) mInitialViewProps.trafficIncidentsCardEnabled = value; + } + + public void setHeaderEnabled(boolean value) { + if (isReady()) { + IGMNNavViewFragment navFragment = getNavFragment(); + if (navFragment != null) { + navFragment.setHeaderEnabled(value); + } + } else if (mInitialViewProps != null) mInitialViewProps.headerEnabled = value; + } + + public void setFooterEnabled(boolean value) { + + if (isReady()) { + IGMNNavViewFragment navFragment = getNavFragment(); + if (navFragment != null) { + navFragment.setEtaCardEnabled(value); + } + } else if (mInitialViewProps != null) mInitialViewProps.footerEnabled = value; + } + + public void setSpeedometerEnabled(boolean value) { + + if (isReady()) { + IGMNNavViewFragment navFragment = getNavFragment(); + if (navFragment != null) { + navFragment.setSpeedometerEnabled(value); + } + } else if (mInitialViewProps != null) mInitialViewProps.speedometerEnabled = value; + } + + public void setSpeedLimitIconEnabled(boolean value) { + if (isReady()) { + IGMNNavViewFragment navFragment = getNavFragment(); + if (navFragment != null) { + navFragment.setSpeedLimitIconEnabled(value); + } + } else if (mInitialViewProps != null) mInitialViewProps.speedLimitIconEnabled = value; + } + + public void setRecenterButtonEnabled(boolean value) { + if (isReady()) { + IGMNNavViewFragment navFragment = getNavFragment(); + if (navFragment != null) { + navFragment.setRecenterButtonEnabled(value); + } + } else if (mInitialViewProps != null) mInitialViewProps.recenterButtonEnabled = value; + } + + public void setNavigationViewStylingOptions(@Nullable ReadableMap value) { + if (isReady() && value != null) { + IGMNNavViewFragment navFragment = getNavFragment(); + if (navFragment != null) { + navFragment.setStylingOptions( + new GMNStylingOptionsBuilder.Builder(value.toHashMap()).build()); + } + } else if (mInitialViewProps != null) mInitialViewProps.navigationViewStylingOptions = value; + } + + public void setNightMode(int value) { + if (isReady()) { + IGMNNavViewFragment navFragment = getNavFragment(); + if (navFragment != null) { + navFragment.setNightModeOption(value); + } + } else if (mInitialViewProps != null) mInitialViewProps.nightMode = value; + } + + public void setFollowingPerspective(int value) { + if (isReady()) { + getMapController().setFollowingPerspective(value); + } else if (mInitialViewProps != null) mInitialViewProps.followingPerspective = value; + } + + public void setMapStyle(@Nullable String value) { + if (isReady()) { + getMapController().setMapStyle(value); + } else if (mInitialViewProps != null) mInitialViewProps.mapStyle = value; + } + + public void setMapToolbarEnabled(boolean value) { + if (isReady()) { + getMapController().setMapToolbarEnabled(value); + } else if (mInitialViewProps != null) mInitialViewProps.mapToolbarEnabled = value; + } + + public void setIndoorEnabled(boolean value) { + if (isReady()) { + getMapController().setIndoorEnabled(value); + } else if (mInitialViewProps != null) mInitialViewProps.indoorEnabled = value; + } + + public void setTrafficEnabled(boolean value) { + if (isReady()) { + getMapController().setTrafficEnabled(value); + } else if (mInitialViewProps != null) mInitialViewProps.trafficEnabled = value; + } + + public void setCompassEnabled(boolean value) { + if (isReady()) { + getMapController().setCompassEnabled(value); + } else if (mInitialViewProps != null) { + mInitialViewProps.initialCompassEnabledSet = true; + mInitialViewProps.compassEnabled = value; + maybeInitFragment(); + } + } + + public void setMyLocationButtonEnabled(boolean value) { + if (isReady()) { + getMapController().setMyLocationButtonEnabled(value); + } else if (mInitialViewProps != null) mInitialViewProps.myLocationButtonEnabled = value; + } + + public void setMyLocationEnabled(boolean value) { + if (isReady()) { + getMapController().setMyLocationEnabled(value); + } else if (mInitialViewProps != null) mInitialViewProps.myLocationEnabled = value; + } + + public void setRotateGesturesEnabled(boolean value) { + if (isReady()) { + getMapController().setRotateGesturesEnabled(value); + } else if (mInitialViewProps != null) { + mInitialViewProps.initialRotateGesturesEnabledSet = true; + mInitialViewProps.rotateGesturesEnabled = value; + maybeInitFragment(); + } + } + + public void setScrollGesturesEnabled(boolean value) { + if (isReady()) { + getMapController().setScrollGesturesEnabled(value); + } else if (mInitialViewProps != null) { + mInitialViewProps.initialScrollGesturesEnabledSet = true; + mInitialViewProps.scrollGesturesEnabled = value; + maybeInitFragment(); + } + } + + public void setScrollGesturesEnabledDuringRotateOrZoom(boolean value) { + if (isReady()) { + getMapController().setScrollGesturesEnabledDuringRotateOrZoom(value); + } else if (mInitialViewProps != null) { + mInitialViewProps.initialScrollGesturesEnabledDuringRotateOrZoomSet = true; + mInitialViewProps.scrollGesturesEnabledDuringRotateOrZoom = value; + maybeInitFragment(); + } + } + + public void setTiltGesturesEnabled(boolean value) { + if (isReady()) { + getMapController().setTiltGesturesEnabled(value); + } else if (mInitialViewProps != null) { + mInitialViewProps.initialTiltGesturesEnabledSet = true; + mInitialViewProps.tiltGesturesEnabled = value; + maybeInitFragment(); + } + } + + public void setZoomControlsEnabled(boolean value) { + if (isReady()) { + getMapController().setZoomControlsEnabled(value); + } else if (mInitialViewProps != null) { + mInitialViewProps.initialZoomControlsEnabledSet = true; + mInitialViewProps.zoomControlsEnabled = value; + maybeInitFragment(); + } + } + + public void setZoomGesturesEnabled(boolean value) { + if (isReady()) { + getMapController().setZoomGesturesEnabled(value); + } else if (mInitialViewProps != null) { + mInitialViewProps.initialZoomGesturesEnabledSet = true; + mInitialViewProps.zoomGesturesEnabled = value; + maybeInitFragment(); + } + } + + public void setBuildingsEnabled(boolean value) { + if (isReady()) { + getMapController().setBuildingsEnabled(value); + } else if (mInitialViewProps != null) mInitialViewProps.buildingsEnabled = value; + } + + public void setReportIncidentButtonEnabled(boolean value) { + if (isReady()) { + IGMNNavViewFragment navFragment = getNavFragment(); + if (navFragment != null) { + navFragment.setReportIncidentButtonEnabled(value); + } + } else if (mInitialViewProps != null) mInitialViewProps.reportIncidentButtonEnabled = value; + } + + public void setMinZoomLevel(@Nullable Float value) { + if (isReady() && value != null) { + getMapController().setMinZoomPreference(value); + } else if (mInitialViewProps != null) { + mInitialViewProps.initialMinZoomPreferenceSet = true; + mInitialViewProps.minZoomPreference = value; + maybeInitFragment(); + } + } + + public void setMaxZoomLevel(@Nullable Float value) { + if (isReady() && value != null) { + getMapController().setMaxZoomPreference(value); + } else if (mInitialViewProps != null) { + mInitialViewProps.initialMaxZoomPreferenceSet = true; + mInitialViewProps.maxZoomPreference = value; + maybeInitFragment(); + } + } + + public void setInitialCameraPosition(@Nullable CameraPosition value) { + if (mInitialViewProps != null) { + mInitialViewProps.initialCameraPositionSet = true; + mInitialViewProps.initialCameraPosition = value; + maybeInitFragment(); + } + } + + public void setMapId(@Nullable String value) { + if (mInitialViewProps != null) { + mInitialViewProps.initialMapIdSet = true; + mInitialViewProps.mapId = value; + maybeInitFragment(); + } + } + + private void startLayoutLoop() { + assert !mLayoutLoopRunning; + assert mFragment != null; + + if (mFrameCallback == null) { + mFrameCallback = + new Choreographer.FrameCallback() { + @Override + public void doFrame(long frameTimeNanos) { + if (!isReady() || mFragment.getView() == null || !mFragment.isAdded()) { + mLayoutLoopRunning = false; + return; + } + + // Update fragments measures and layout. + updateFragmentMeasures(); + updateFragmentLayout(); + + // Dispatch global layout event for this GMNMapViewLayout. + // This signals that this view's layout (including its children) is complete for this + // frame. + if (getViewTreeObserver().isAlive()) { + getViewTreeObserver().dispatchOnGlobalLayout(); + } + + if (isReady()) { + // Continue the loop for the next frame. + Choreographer.getInstance().postFrameCallback(this); + } else { + mLayoutLoopRunning = false; + } + } + }; + } + + // Start the loop. + Choreographer.getInstance().removeFrameCallback(mFrameCallback); + Choreographer.getInstance().postFrameCallback(mFrameCallback); + mLayoutLoopRunning = true; + } + + private void stopLayoutLoop() { + mIsMapReady = false; + if (mFrameCallback != null && mLayoutLoopRunning) { + Choreographer.getInstance().removeFrameCallback(mFrameCallback); + } + mLayoutLoopRunning = false; + } +} diff --git a/android/src/main/java/com/google/maps/android/rn/navsdk/GMNMarker.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNMarker.java new file mode 100644 index 00000000..b568d35a --- /dev/null +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNMarker.java @@ -0,0 +1,23 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.maps.android.rn.navsdk; + +import androidx.annotation.Nullable; +import com.google.android.gms.maps.model.Marker; + +/** Immutable wrapper for a Google Maps Marker and an optional RN ID. */ +public record GMNMarker(Marker marker, @Nullable String rnId) {} diff --git a/android/src/main/java/com/google/android/react/navsdk/NavAutoModule.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavAutoModule.java similarity index 54% rename from android/src/main/java/com/google/android/react/navsdk/NavAutoModule.java rename to android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavAutoModule.java index f137b340..ed5ed32e 100644 --- a/android/src/main/java/com/google/android/react/navsdk/NavAutoModule.java +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavAutoModule.java @@ -11,51 +11,42 @@ * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.react.navsdk; +package com.google.maps.android.rn.navsdk; import android.location.Location; import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.CatalystInstance; -import com.facebook.react.bridge.NativeArray; import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.UiThreadUtil; import com.facebook.react.bridge.WritableMap; -import com.facebook.react.bridge.WritableNativeArray; +import com.facebook.react.module.annotations.ReactModule; import com.google.android.gms.maps.UiSettings; import com.google.android.gms.maps.model.CameraPosition; -import com.google.android.gms.maps.model.Circle; import com.google.android.gms.maps.model.LatLng; -import com.google.android.gms.maps.model.Marker; -import com.google.android.gms.maps.model.Polygon; -import com.google.android.gms.maps.model.Polyline; import com.google.android.libraries.navigation.StylingOptions; import java.util.Map; /** - * This exposes a series of methods that can be called diretly from the React Native code. They have - * been implemented using promises as it's not recommended for them to be synchronous. + * This exposes a series of methods that can be called directly from the React Native code. They + * have been implemented using promises as it's not recommended for them to be synchronous. */ -public class NavAutoModule extends ReactContextBaseJavaModule implements INavigationAutoCallback { - public static final String REACT_CLASS = "NavAutoModule"; - private static final String TAG = "AndroidAutoModule"; - private static NavAutoModule instance; +@ReactModule(name = GMNNavAutoModule.NAME) +public class GMNNavAutoModule extends NativeNavAutoModuleSpec + implements IGMNNavigationAutoCallback { + private static GMNNavAutoModule instance; private static ModuleReadyListener moduleReadyListener; ReactApplicationContext reactContext; - private MapViewController mMapViewController; + private GMNMapViewController mMapViewController; private StylingOptions mStylingOptions; - private INavigationViewController mNavigationViewController; + private IGMNNavigationViewController mNavigationViewController; public interface ModuleReadyListener { void onModuleReady(); } - public NavAutoModule(ReactApplicationContext reactContext) { + public GMNNavAutoModule(ReactApplicationContext reactContext) { super(reactContext); this.reactContext = reactContext; instance = this; @@ -64,15 +55,10 @@ public NavAutoModule(ReactApplicationContext reactContext) { } } - @Override - public String getName() { - return REACT_CLASS; - } - - // Called by the AndroidAuto implementation. See SampleApp for example. - public static synchronized NavAutoModule getInstance() { + // Called by the AndroidAuto implementation. See NavigationSdkExample for example. + public static synchronized GMNNavAutoModule getInstance() { if (instance == null) { - throw new IllegalStateException(REACT_CLASS + " instance is null"); + throw new IllegalStateException(NAME + " instance is null"); } return instance; } @@ -85,7 +71,8 @@ public static void setModuleReadyListener(ModuleReadyListener listener) { } public void androidAutoNavigationScreenInitialized( - MapViewController mapViewController, INavigationViewController navigationViewController) { + GMNMapViewController mapViewController, + IGMNNavigationViewController navigationViewController) { mMapViewController = mapViewController; mNavigationViewController = navigationViewController; if (mStylingOptions != null && mNavigationViewController != null) { @@ -101,24 +88,27 @@ public void androidAutoNavigationScreenDisposed() { } public void setStylingOptions(Map stylingOptions) { - mStylingOptions = new StylingOptionsBuilder.Builder(stylingOptions).build(); - if (mStylingOptions != null && mNavigationViewController != null) { - mNavigationViewController.setStylingOptions(mStylingOptions); - } + mStylingOptions = new GMNStylingOptionsBuilder.Builder(stylingOptions).build(); + UiThreadUtil.runOnUiThread( + () -> { + if (mStylingOptions != null && mNavigationViewController != null) { + mNavigationViewController.setStylingOptions(mStylingOptions); + } + }); } - @ReactMethod - public void setMapType(int jsValue) { + @Override + public void setMapType(double jsValue) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { return; } - mMapViewController.setMapType(jsValue); + mMapViewController.setMapType((int) jsValue); }); } - @ReactMethod + @Override public void setMapStyle(String url) { UiThreadUtil.runOnUiThread( () -> { @@ -129,265 +119,261 @@ public void setMapStyle(String url) { }); } - @ReactMethod - public void setMapToolbarEnabled(boolean isOn) { + @Override + public void addCircle(ReadableMap options, final Promise promise) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); return; } - mMapViewController.setMapToolbarEnabled(isOn); - }); - } + GMNCircle circle = mMapViewController.addCircle(options.toHashMap()); - @ReactMethod - public void addCircle(ReadableMap circleOptionsMap, final Promise promise) { - UiThreadUtil.runOnUiThread( - () -> { - if (mMapViewController == null) { - promise.reject(JsErrors.NO_MAP_ERROR_CODE, JsErrors.NO_MAP_ERROR_MESSAGE); + if (circle == null) { + promise.reject( + GMNJsErrors.FAILED_TO_CREATE_MAP_OBJECT_ERROR_CODE, + GMNJsErrors.FAILED_TO_CREATE_MAP_OBJECT_ERROR_MESSAGE); return; } - Circle circle = mMapViewController.addCircle(circleOptionsMap.toHashMap()); - promise.resolve(ObjectTranslationUtil.getMapFromCircle(circle)); + promise.resolve(GMNObjectTranslationUtil.getMapFromCircle(circle)); }); } - @ReactMethod - public void addMarker(ReadableMap markerOptionsMap, final Promise promise) { + @Override + public void addMarker(ReadableMap options, final Promise promise) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { - promise.reject(JsErrors.NO_MAP_ERROR_CODE, JsErrors.NO_MAP_ERROR_MESSAGE); + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); return; } - Marker marker = mMapViewController.addMarker(markerOptionsMap.toHashMap()); - - promise.resolve(ObjectTranslationUtil.getMapFromMarker(marker)); - }); - } + GMNMarker marker = mMapViewController.addMarker(options.toHashMap()); - @ReactMethod - public void addPolyline(ReadableMap polylineOptionsMap, final Promise promise) { - UiThreadUtil.runOnUiThread( - () -> { - if (mMapViewController == null) { - promise.reject(JsErrors.NO_MAP_ERROR_CODE, JsErrors.NO_MAP_ERROR_MESSAGE); + if (marker == null) { + promise.reject( + GMNJsErrors.FAILED_TO_CREATE_MAP_OBJECT_ERROR_CODE, + GMNJsErrors.FAILED_TO_CREATE_MAP_OBJECT_ERROR_MESSAGE); return; } - Polyline polyline = mMapViewController.addPolyline(polylineOptionsMap.toHashMap()); - promise.resolve(ObjectTranslationUtil.getMapFromPolyline(polyline)); + promise.resolve(GMNObjectTranslationUtil.getMapFromMarker(marker)); }); } - @ReactMethod - public void addPolygon(ReadableMap polygonOptionsMap, final Promise promise) { + @Override + public void addPolyline(ReadableMap options, final Promise promise) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { - promise.reject(JsErrors.NO_MAP_ERROR_CODE, JsErrors.NO_MAP_ERROR_MESSAGE); + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); + return; + } + GMNPolyline polyline = mMapViewController.addPolyline(options.toHashMap()); + + if (polyline == null) { + promise.reject( + GMNJsErrors.FAILED_TO_CREATE_MAP_OBJECT_ERROR_CODE, + GMNJsErrors.FAILED_TO_CREATE_MAP_OBJECT_ERROR_MESSAGE); return; } - Polygon polygon = mMapViewController.addPolygon(polygonOptionsMap.toHashMap()); - promise.resolve(ObjectTranslationUtil.getMapFromPolygon(polygon)); + promise.resolve(GMNObjectTranslationUtil.getMapFromPolyline(polyline)); }); } - @ReactMethod - public void removeCircle(String id) { + @Override + public void addPolygon(ReadableMap options, final Promise promise) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); return; } - mMapViewController.removeCircle(id); - }); - } + GMNPolygon polygon = mMapViewController.addPolygon(options.toHashMap()); - @ReactMethod - public void removeMarker(String id) { - UiThreadUtil.runOnUiThread( - () -> { - if (mMapViewController == null) { + if (polygon == null) { + promise.reject( + GMNJsErrors.FAILED_TO_CREATE_MAP_OBJECT_ERROR_CODE, + GMNJsErrors.FAILED_TO_CREATE_MAP_OBJECT_ERROR_MESSAGE); return; } - mMapViewController.removeMarker(id); + + promise.resolve(GMNObjectTranslationUtil.getMapFromPolygon(polygon)); }); } - @ReactMethod - public void removePolyline(String id) { + @Override + public void addGroundOverlay(ReadableMap options, Promise promise) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); return; } - mMapViewController.removePolyline(id); - }); - } + GMNGroundOverlay overlay = mMapViewController.addGroundOverlay(options.toHashMap()); - @ReactMethod - public void removePolygon(String id) { - UiThreadUtil.runOnUiThread( - () -> { - if (mMapViewController == null) { + if (overlay == null) { + promise.reject( + GMNJsErrors.FAILED_TO_CREATE_MAP_OBJECT_ERROR_CODE, + GMNJsErrors.FAILED_TO_CREATE_MAP_OBJECT_ERROR_MESSAGE); return; } - mMapViewController.removePolygon(id); + + promise.resolve(GMNObjectTranslationUtil.getMapFromGroundOverlay(overlay)); }); } - @ReactMethod - public void clearMapView() { + @Override + public void removeCircle(String id, Promise promise) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); return; } - mMapViewController.clearMapView(); + mMapViewController.removeCircle(id); + promise.resolve(true); }); } - @ReactMethod - public void setIndoorEnabled(Boolean isOn) { + @Override + public void removeGroundOverlay(String id, Promise promise) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); return; } - mMapViewController.setIndoorEnabled(isOn); + mMapViewController.removeGroundOverlay(id); + promise.resolve(true); }); } - @ReactMethod - public void setTrafficEnabled(Boolean isOn) { + @Override + public void removeMarker(String id, Promise promise) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); return; } - mMapViewController.setTrafficEnabled(isOn); + mMapViewController.removeMarker(id); + promise.resolve(true); }); } - @ReactMethod - public void setCompassEnabled(Boolean isOn) { + @Override + public void removePolyline(String id, Promise promise) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); return; } - mMapViewController.setCompassEnabled(isOn); + mMapViewController.removePolyline(id); + promise.resolve(true); }); } - @ReactMethod - public void setMyLocationButtonEnabled(Boolean isOn) { + @Override + public void removePolygon(String id, Promise promise) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); return; } - mMapViewController.setMyLocationButtonEnabled(isOn); + mMapViewController.removePolygon(id); + promise.resolve(true); }); } - @ReactMethod - public void setMyLocationEnabled(Boolean isOn) { + @Override + public void clearMapView(Promise promise) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); return; } - mMapViewController.setMyLocationEnabled(isOn); + mMapViewController.clearMapView(); + promise.resolve(true); }); } - @ReactMethod - public void setRotateGesturesEnabled(Boolean isOn) { + @Override + public void setIndoorEnabled(boolean isOn) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { return; } - mMapViewController.setRotateGesturesEnabled(isOn); + mMapViewController.setIndoorEnabled(isOn); }); } - @ReactMethod - public void setScrollGesturesEnabled(Boolean isOn) { + @Override + public void setTrafficEnabled(boolean isOn) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { return; } - mMapViewController.setScrollGesturesEnabled(isOn); + mMapViewController.setTrafficEnabled(isOn); }); } - @ReactMethod - public void setScrollGesturesEnabledDuringRotateOrZoom(Boolean isOn) { + @Override + public void setCompassEnabled(boolean isOn) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { return; } - mMapViewController.setScrollGesturesEnabledDuringRotateOrZoom(isOn); + mMapViewController.setCompassEnabled(isOn); }); } - @ReactMethod - public void setZoomControlsEnabled(Boolean isOn) { + @Override + public void setMyLocationEnabled(boolean isOn) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { return; } - mMapViewController.setZoomControlsEnabled(isOn); + mMapViewController.setMyLocationEnabled(isOn); }); } - @ReactMethod - public void setZoomLevel(final Integer level, final Promise promise) { + @Override + public void setZoomLevel(final double level, final Promise promise) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { - promise.reject(JsErrors.NO_MAP_ERROR_CODE, JsErrors.NO_MAP_ERROR_MESSAGE); + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); return; } - mMapViewController.setZoomLevel(level); + mMapViewController.setZoomLevel((int) level); promise.resolve(true); }); } - @ReactMethod - public void setTiltGesturesEnabled(Boolean isOn) { + @Override + public void setMapPadding(double top, double left, double bottom, double right) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { return; } - mMapViewController.setTiltGesturesEnabled(isOn); - }); - } - @ReactMethod - public void setZoomGesturesEnabled(Boolean isOn) { - UiThreadUtil.runOnUiThread( - () -> { - if (mMapViewController == null) { - return; - } - mMapViewController.setZoomGesturesEnabled(isOn); + mMapViewController.setPadding((int) top, (int) left, (int) bottom, (int) right); }); } - @ReactMethod - public void setBuildingsEnabled(Boolean isOn) { + @Override + public void setBuildingsEnabled(boolean isOn) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { @@ -397,45 +383,40 @@ public void setBuildingsEnabled(Boolean isOn) { }); } - @ReactMethod + @Override public void getCameraPosition(final Promise promise) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { - promise.reject(JsErrors.NO_MAP_ERROR_CODE, JsErrors.NO_MAP_ERROR_MESSAGE); + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); return; } CameraPosition cp = mMapViewController.getGoogleMap().getCameraPosition(); - if (cp == null) { - promise.resolve(null); - return; - } - LatLng target = cp.target; WritableMap map = Arguments.createMap(); map.putDouble("bearing", cp.bearing); map.putDouble("tilt", cp.tilt); map.putDouble("zoom", cp.zoom); - map.putMap("target", ObjectTranslationUtil.getMapFromLatLng(target)); + map.putMap("target", GMNObjectTranslationUtil.getMapFromLatLng(target)); promise.resolve(map); }); } - @ReactMethod + @Override public void getMyLocation(final Promise promise) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { - promise.reject(JsErrors.NO_MAP_ERROR_CODE, JsErrors.NO_MAP_ERROR_MESSAGE); + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); return; } try { Location location = mMapViewController.getGoogleMap().getMyLocation(); - promise.resolve(ObjectTranslationUtil.getMapFromLocation(location)); + promise.resolve(GMNObjectTranslationUtil.getMapFromLocation(location)); } catch (Exception e) { promise.resolve(null); return; @@ -443,12 +424,12 @@ public void getMyLocation(final Promise promise) { }); } - @ReactMethod + @Override public void getUiSettings(final Promise promise) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { - promise.reject(JsErrors.NO_MAP_ERROR_CODE, JsErrors.NO_MAP_ERROR_MESSAGE); + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); return; } @@ -476,12 +457,12 @@ public void getUiSettings(final Promise promise) { }); } - @ReactMethod + @Override public void isMyLocationEnabled(final Promise promise) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { - promise.reject(JsErrors.NO_MAP_ERROR_CODE, JsErrors.NO_MAP_ERROR_MESSAGE); + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); return; } @@ -489,62 +470,32 @@ public void isMyLocationEnabled(final Promise promise) { }); } - @ReactMethod - public void moveCamera(ReadableMap map) { + @Override + public void moveCamera(ReadableMap map, Promise promise) { UiThreadUtil.runOnUiThread( () -> { if (mMapViewController == null) { + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); return; } - - mMapViewController.moveCamera(map.toHashMap()); + Map cameraMap = map.toHashMap(); + mMapViewController.moveCamera( + GMNObjectTranslationUtil.getCameraPositionFromMap(cameraMap)); + promise.resolve(true); }); } - @ReactMethod + @Override public void isAutoScreenAvailable(final Promise promise) { promise.resolve(mMapViewController != null); } - @ReactMethod - public void setPadding( - final Integer top, final Integer left, final Integer bottom, final Integer right) { - UiThreadUtil.runOnUiThread( - () -> { - if (mMapViewController == null) { - return; - } - - mMapViewController.setPadding(top, left, bottom, right); - }); - } - public void sendScreenState(boolean available) { - WritableNativeArray params = new WritableNativeArray(); - params.pushBoolean(available); - - sendCommandToReactNative("onAutoScreenAvailabilityChanged", params); + emitOnAutoScreenAvailabilityChanged(available); } @Override public void onCustomNavigationAutoEvent(String type, ReadableMap data) { - WritableMap map = Arguments.createMap(); - map.putString("type", type); - map.putMap("data", data); - - WritableNativeArray params = new WritableNativeArray(); - params.pushMap(map); - - sendCommandToReactNative("onCustomNavigationAutoEvent", params); - } - - /** Send command to react native. */ - private void sendCommandToReactNative(String functionName, NativeArray params) { - ReactContext reactContext = getReactApplicationContext(); - - if (reactContext != null) { - CatalystInstance catalystInstance = reactContext.getCatalystInstance(); - catalystInstance.callFunction(Constants.NAV_AUTO_JAVASCRIPT_FLAG, functionName, params); - } + emitOnCustomNavigationAutoEvent(data); } } diff --git a/android/src/main/java/com/google/android/react/navsdk/NavForwardingManager.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavForwardingManager.java similarity index 85% rename from android/src/main/java/com/google/android/react/navsdk/NavForwardingManager.java rename to android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavForwardingManager.java index 734069f7..b0f001b7 100644 --- a/android/src/main/java/com/google/android/react/navsdk/NavForwardingManager.java +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavForwardingManager.java @@ -11,20 +11,20 @@ * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.react.navsdk; +package com.google.maps.android.rn.navsdk; import android.content.Context; import com.google.android.libraries.navigation.Navigator; /** Starts and stops the forwarding of turn-by-turn nav info from Nav SDK. */ -public class NavForwardingManager { +public class GMNNavForwardingManager { /** Registers a service to receive navigation updates from nav info */ public static void startNavForwarding( - Navigator navigator, Context context, INavigationCallback navigationCallback) { + Navigator navigator, Context context, IGMNNavigationCallback navigationCallback) { boolean success = navigator.registerServiceForNavUpdates( context.getPackageName(), - NavInfoReceivingService.class.getName(), + GMNNavInfoReceivingService.class.getName(), /* numNextStepsToPreview= */ Integer.MAX_VALUE); // Send all remaining steps. if (success) { navigationCallback.logDebugInfo("Successfully registered service for nav updates"); @@ -35,7 +35,7 @@ public static void startNavForwarding( /** Unregisters the service receiving navigation updates */ public static void stopNavForwarding( - Navigator navigator, Context context, INavigationCallback navigationCallback) { + Navigator navigator, Context context, IGMNNavigationCallback navigationCallback) { // Unregister the nav info receiving service. boolean success = navigator.unregisterServiceForNavUpdates(); if (success) { diff --git a/android/src/main/java/com/google/android/react/navsdk/NavInfoReceivingService.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavInfoReceivingService.java similarity index 96% rename from android/src/main/java/com/google/android/react/navsdk/NavInfoReceivingService.java rename to android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavInfoReceivingService.java index 359d6b98..dbca5191 100644 --- a/android/src/main/java/com/google/android/react/navsdk/NavInfoReceivingService.java +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavInfoReceivingService.java @@ -11,7 +11,7 @@ * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.react.navsdk; +package com.google.maps.android.rn.navsdk; import android.app.Service; import android.content.Intent; @@ -35,7 +35,7 @@ * to structure your app. The service binding will be able to handle interprocess communication to * receive nav info messages from the main process. */ -public class NavInfoReceivingService extends Service { +public class GMNNavInfoReceivingService extends Service { /** The messenger used by the service to receive nav step updates. */ private Messenger mIncomingMessenger; diff --git a/android/src/main/java/com/google/android/react/navsdk/NavModule.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavModule.java similarity index 65% rename from android/src/main/java/com/google/android/react/navsdk/NavModule.java rename to android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavModule.java index 875b8f3e..2181a092 100644 --- a/android/src/main/java/com/google/android/react/navsdk/NavModule.java +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavModule.java @@ -11,34 +11,30 @@ * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.react.navsdk; +package com.google.maps.android.rn.navsdk; +import android.app.Activity; import android.location.Location; import androidx.annotation.Nullable; import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.Observer; import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.CatalystInstance; import com.facebook.react.bridge.LifecycleEventListener; -import com.facebook.react.bridge.NativeArray; import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.UiThreadUtil; import com.facebook.react.bridge.WritableArray; import com.facebook.react.bridge.WritableMap; -import com.facebook.react.bridge.WritableNativeArray; +import com.facebook.react.module.annotations.ReactModule; import com.google.android.gms.maps.model.LatLng; import com.google.android.libraries.mapsplatform.turnbyturn.model.NavInfo; import com.google.android.libraries.mapsplatform.turnbyturn.model.StepInfo; import com.google.android.libraries.navigation.ArrivalEvent; import com.google.android.libraries.navigation.ListenableResultFuture; import com.google.android.libraries.navigation.NavigationApi; -import com.google.android.libraries.navigation.NavigationApi.OnTermsResponseListener; import com.google.android.libraries.navigation.Navigator; import com.google.android.libraries.navigation.RoadSnappedLocationProvider; import com.google.android.libraries.navigation.RoadSnappedLocationProvider.LocationListener; @@ -53,25 +49,24 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.CopyOnWriteArrayList; /** * This exposes a series of methods that can be called diretly from the React Native code. They have * been implemented using promises as it's not recommended for them to be synchronous. */ -public class NavModule extends ReactContextBaseJavaModule - implements INavigationCallback, LifecycleEventListener { - public static final String REACT_CLASS = "NavModule"; - private static final String TAG = "NavModule"; - private static NavModule instance; +@ReactModule(name = GMNNavModule.NAME) +public class GMNNavModule extends NativeNavModuleSpec + implements IGMNNavigationCallback, LifecycleEventListener { + private static GMNNavModule instance; private static ModuleReadyListener moduleReadyListener; ReactApplicationContext reactContext; private Navigator mNavigator; - private ArrayList mWaypoints = new ArrayList<>(); - private ListenableResultFuture pendingRoute; + private final ArrayList mWaypoints = new ArrayList<>(); private RoadSnappedLocationProvider mRoadSnappedLocationProvider; - private NavViewManager mNavViewManager; + private GMNNavViewManager mNavViewManager; private final CopyOnWriteArrayList mNavigationReadyListeners = new CopyOnWriteArrayList<>(); private boolean mIsListeningRoadSnappedLocation = false; @@ -93,29 +88,34 @@ public interface NavigationReadyListener { void onReady(boolean ready); } - public NavModule(ReactApplicationContext reactContext, NavViewManager navViewManager) { + public GMNNavModule(ReactApplicationContext reactContext, GMNNavViewManager navViewManager) { super(reactContext); setReactContext(reactContext); setViewManager(navViewManager); - if (moduleReadyListener != null) { - moduleReadyListener.onModuleReady(); - } } - public static synchronized NavModule getInstance( - ReactApplicationContext reactContext, NavViewManager navViewManager) { + public static synchronized GMNNavModule getInstance( + ReactApplicationContext reactContext, GMNNavViewManager navViewManager) { if (instance == null) { - instance = new NavModule(reactContext, navViewManager); + instance = new GMNNavModule(reactContext, navViewManager); } else { instance.setReactContext(reactContext); instance.setViewManager(navViewManager); } + if (moduleReadyListener != null) { + moduleReadyListener.onModuleReady(); + moduleReadyListener = null; + } return instance; } - public static synchronized NavModule getInstance() { + public static synchronized boolean hasInstance() { + return instance != null; + } + + public static synchronized GMNNavModule getInstance() { if (instance == null) { - throw new IllegalStateException(REACT_CLASS + " instance is null"); + throw new IllegalStateException(NAME + " instance is null"); } return instance; } @@ -125,7 +125,7 @@ public void setReactContext(ReactApplicationContext reactContext) { this.reactContext.addLifecycleEventListener(this); } - public void setViewManager(NavViewManager navViewManager) { + public void setViewManager(GMNNavViewManager navViewManager) { mNavViewManager = navViewManager; } @@ -141,18 +141,7 @@ public Navigator getNavigator() { } @Override - public String getName() { - return REACT_CLASS; - } - - @Override - public Map getConstants() { - final Map constants = new HashMap<>(); - return constants; - } - - @ReactMethod - private void cleanup() { + public void cleanup(Promise promise) { stopUpdatingLocation(); removeNavigationListeners(); mWaypoints.clear(); @@ -165,20 +154,22 @@ private void cleanup() { () -> { mNavigator.clearDestinations(); mNavigator.cleanup(); + promise.resolve(null); }); } - @ReactMethod + @Override public void initializeNavigator( - @Nullable ReadableMap tocParams, int taskRemovedBehaviourJsValue) { + ReadableMap tocParams, double taskRemovedBehaviourJsValue, Promise promise) { this.tocParamsMap = tocParams.toHashMap(); this.taskRemovedBehaviour = - EnumTranslationUtil.getTaskRemovedBehaviourFromJsValue(taskRemovedBehaviourJsValue); + GMNEnumTranslationUtil.getTaskRemovedBehaviourFromJsValue( + (int) taskRemovedBehaviourJsValue); if (getTermsAccepted()) { - initializeNavigationApi(); + initializeNavigationApi(promise); } else { - this.showTermsAndConditionsDialog(); + this.showTermsAndConditionsDialogAndInitializeNavigationApi(promise); } // Observe live data for nav info updates. @@ -186,15 +177,16 @@ public void initializeNavigator( UiThreadUtil.runOnUiThread( () -> { - NavInfoReceivingService.getNavInfoLiveData() - .observe((LifecycleOwner) getCurrentActivity(), navInfoObserver); + GMNNavInfoReceivingService.getNavInfoLiveData() + .observe( + (LifecycleOwner) Objects.requireNonNull(getCurrentActivity()), navInfoObserver); }); } private void onNavigationReady() { mNavViewManager.applyStylingOptions(); - sendCommandToReactNative("onNavigationReady", (NativeArray) null); + emitOnNavigationReady(); for (NavigationReadyListener listener : mNavigationReadyListeners) { listener.onReady(true); @@ -214,14 +206,10 @@ public void unRegisterNavigationReadyListener(NavigationReadyListener listener) mNavigationReadyListeners.remove(listener); } - private void onNavigationInitError(int errorCode) { - sendCommandToReactNative("onNavigationInitError", String.valueOf(errorCode)); - } - /** Starts the Navigation API, saving a reference to the ready Navigator instance. */ - private void initializeNavigationApi() { + private void initializeNavigationApi(Promise promise) { NavigationApi.getNavigator( - getCurrentActivity().getApplication(), + Objects.requireNonNull(getCurrentActivity()).getApplication(), new NavigationApi.NavigatorListener() { @Override public void onNavigatorReady(Navigator navigator) { @@ -231,10 +219,12 @@ public void onNavigatorReady(Navigator navigator) { if (mRoadSnappedLocationProvider == null) { mRoadSnappedLocationProvider = NavigationApi.getRoadSnappedLocationProvider( - getCurrentActivity().getApplication()); + Objects.requireNonNull(getCurrentActivity()).getApplication()); } registerNavigationListeners(); onNavigationReady(); + // 0: OK. + promise.resolve(0); } @Override @@ -253,31 +243,30 @@ public void onError(@NavigationApi.ErrorCode int errorCode) { + " Use."; logDebugInfo(errMsg); break; - case NavigationApi.ErrorCode.NETWORK_ERROR: - errMsg = "Error loading Navigation API: Network error"; + case NavigationApi.ErrorCode.LOCATION_PERMISSION_MISSING: + errMsg = "Error loading Navigation API: Location permission is not granted"; logDebugInfo(errMsg); break; default: - errMsg = "Error loading Navigation API: Location permission is not granted"; + errMsg = "Error loading Navigation API"; logDebugInfo(errMsg); } - onNavigationInitError(errorCode); + promise.resolve(errorCode); } }); } - /** - * Enable turn by turn logging using background service - * - * @param isEnabled - */ + /** Enable turn by turn logging using background service */ @ReactMethod public void setTurnByTurnLoggingEnabled(boolean isEnabled) { - if (isEnabled) { - NavForwardingManager.startNavForwarding(mNavigator, getCurrentActivity(), this); - } else { - NavForwardingManager.stopNavForwarding(mNavigator, getCurrentActivity(), this); + Activity activity = getCurrentActivity(); + if (activity != null) { + if (isEnabled) { + GMNNavForwardingManager.startNavForwarding(mNavigator, activity, this); + } else { + GMNNavForwardingManager.stopNavForwarding(mNavigator, activity, this); + } } } @@ -294,13 +283,11 @@ private void registerNavigationListeners() { public void onArrival(ArrivalEvent arrivalEvent) { WritableMap map = Arguments.createMap(); map.putMap( - "waypoint", ObjectTranslationUtil.getMapFromWaypoint(arrivalEvent.getWaypoint())); + "waypoint", + GMNObjectTranslationUtil.getMapFromWaypoint(arrivalEvent.getWaypoint())); map.putBoolean("isFinalDestination", arrivalEvent.isFinalDestination()); - WritableNativeArray params = new WritableNativeArray(); - params.pushMap(map); - - sendCommandToReactNative("onArrival", params); + emitOnArrival(map); } }; mNavigator.addArrivalListener(mArrivalListener); @@ -309,7 +296,7 @@ public void onArrival(ArrivalEvent arrivalEvent) { new Navigator.RouteChangedListener() { @Override public void onRouteChanged() { - sendCommandToReactNative("onRouteChanged", (NativeArray) null); + emitOnRouteChanged(); } }; mNavigator.addRouteChangedListener(mRouteChangedListener); @@ -318,7 +305,7 @@ public void onRouteChanged() { new Navigator.TrafficUpdatedListener() { @Override public void onTrafficUpdated() { - sendCommandToReactNative("onTrafficUpdated", (NativeArray) null); + emitOnTrafficUpdated(); } }; mNavigator.addTrafficUpdatedListener(mTrafficUpdatedListener); @@ -327,7 +314,7 @@ public void onTrafficUpdated() { new Navigator.ReroutingListener() { @Override public void onReroutingRequestedByOffRoute() { - sendCommandToReactNative("onReroutingRequestedByOffRoute", (NativeArray) null); + emitOnReroutingRequestedByOffRoute(); } }; mNavigator.addReroutingListener(mReroutingListener); @@ -336,7 +323,7 @@ public void onReroutingRequestedByOffRoute() { new Navigator.RemainingTimeOrDistanceChangedListener() { @Override public void onRemainingTimeOrDistanceChanged() { - sendCommandToReactNative("onRemainingTimeOrDistanceChanged", (NativeArray) null); + emitOnRemainingTimeOrDistanceChanged(); } }; mNavigator.addRemainingTimeOrDistanceChangedListener( @@ -362,9 +349,9 @@ private void removeNavigationListeners() { } } - private void createWaypoint(Map map) { - String placeId = CollectionUtil.getString("placeId", map); - String title = CollectionUtil.getString("title", map); + private void createWaypoint(Map map) { + String placeId = GMNCollectionUtil.getString("placeId", map); + String title = GMNCollectionUtil.getString("title", map); Double lat = null; Double lng = null; @@ -375,8 +362,8 @@ private void createWaypoint(Map map) { if (latlng.get("lng") != null) lng = Double.parseDouble(latlng.get("lng").toString()); } - boolean vehicleStopover = CollectionUtil.getBool("vehicleStopover", map, false); - boolean preferSameSideOfRoad = CollectionUtil.getBool("preferSameSideOfRoad", map, false); + boolean vehicleStopover = GMNCollectionUtil.getBool("vehicleStopover", map, false); + boolean preferSameSideOfRoad = GMNCollectionUtil.getBool("preferSameSideOfRoad", map, false); try { Waypoint.Builder waypointBuilder = @@ -402,105 +389,96 @@ private void createWaypoint(Map map) { } } - @ReactMethod - public void setDestination( - ReadableMap waypoint, - @Nullable ReadableMap routingOptions, - @Nullable ReadableMap displayOptions) { - WritableArray array = new WritableNativeArray(); - array.pushMap(waypoint); - setDestinations(array, routingOptions, displayOptions); - } - - @ReactMethod + @Override public void setDestinations( ReadableArray waypoints, @Nullable ReadableMap routingOptions, - @Nullable ReadableMap displayOptions) { + @Nullable ReadableMap displayOptions, + Promise promise) { if (mNavigator == null) { - // TODO: HANDLE THIS + promise.reject(GMNJsErrors.NO_NAVIGATOR_ERROR_CODE, GMNJsErrors.NO_NAVIGATOR_ERROR_MESSAGE); return; } - pendingRoute = null; // reset pendingRoute. mWaypoints.clear(); // reset waypoints // Set up a waypoint for each place that we want to go to. for (int i = 0; i < waypoints.size(); i++) { - Map map = waypoints.getMap(i).toHashMap(); + Map map = Objects.requireNonNull(waypoints.getMap(i)).toHashMap(); createWaypoint(map); } + ListenableResultFuture pendingRoute; if (routingOptions != null) { if (displayOptions != null) { pendingRoute = mNavigator.setDestinations( mWaypoints, - ObjectTranslationUtil.getRoutingOptionsFromMap(routingOptions.toHashMap()), - ObjectTranslationUtil.getDisplayOptionsFromMap(displayOptions.toHashMap())); + GMNObjectTranslationUtil.getRoutingOptionsFromMap(routingOptions.toHashMap()), + GMNObjectTranslationUtil.getDisplayOptionsFromMap(displayOptions.toHashMap())); } else { pendingRoute = mNavigator.setDestinations( mWaypoints, - ObjectTranslationUtil.getRoutingOptionsFromMap(routingOptions.toHashMap())); + GMNObjectTranslationUtil.getRoutingOptionsFromMap(routingOptions.toHashMap())); } } else { pendingRoute = mNavigator.setDestinations(mWaypoints); } - setOnResultListener( - new IRouteStatusResult() { - @Override - public void onResult(Navigator.RouteStatus code) { - sendCommandToReactNative("onRouteStatusResult", code.toString()); - } + pendingRoute.setOnResultListener( + code -> { + promise.resolve(code.ordinal()); }); } - @ReactMethod - public void clearDestinations() { - if (mNavigator != null) { - mWaypoints.clear(); // reset waypoints - mNavigator.clearDestinations(); + @Override + public void clearDestinations(Promise promise) { + if (mNavigator == null) { + promise.reject(GMNJsErrors.NO_NAVIGATOR_ERROR_CODE, GMNJsErrors.NO_NAVIGATOR_ERROR_MESSAGE); + return; } + mWaypoints.clear(); // reset waypoints + mNavigator.clearDestinations(); + promise.resolve(null); } - @ReactMethod - public void continueToNextDestination() { - if (mNavigator != null) { - mNavigator.continueToNextDestination(); + @Override + public void continueToNextDestination(Promise promise) { + if (mNavigator == null) { + promise.reject(GMNJsErrors.NO_NAVIGATOR_ERROR_CODE, GMNJsErrors.NO_NAVIGATOR_ERROR_MESSAGE); + return; } - } - private void setOnResultListener(IRouteStatusResult listener) { - // Set an action to perform when a route is determined to the destination - if (pendingRoute != null) - pendingRoute.setOnResultListener( - new ListenableResultFuture.OnResultListener() { - @Override - public void onResult(Navigator.RouteStatus code) { - listener.onResult(code); - } - }); + mNavigator.continueToNextDestination(); + promise.resolve(null); } - @ReactMethod - public void startGuidance() { + @Override + public void startGuidance(Promise promise) { if (mWaypoints.isEmpty()) { + promise.reject( + GMNJsErrors.NO_WAYPOINTS_GUIDANCE_ERROR_CODE, + GMNJsErrors.NO_WAYPOINTS_GUIDANCE_ERROR_MESSAGE); + } + + if (mNavigator == null) { + promise.reject(GMNJsErrors.NO_NAVIGATOR_ERROR_CODE, GMNJsErrors.NO_NAVIGATOR_ERROR_MESSAGE); return; } mNavigator.startGuidance(); - sendCommandToReactNative("onStartGuidance", (NativeArray) null); + emitOnStartGuidance(); + promise.resolve(true); } - @ReactMethod - public void stopGuidance() { + @Override + public void stopGuidance(Promise promise) { mNavigator.stopGuidance(); } - @ReactMethod - public void simulateLocationsAlongExistingRoute(float speedMultiplier) { + @Override + public void simulateLocationsAlongExistingRoute(ReadableMap options, Promise promise) { if (mWaypoints.isEmpty()) { return; } @@ -508,31 +486,50 @@ public void simulateLocationsAlongExistingRoute(float speedMultiplier) { mNavigator .getSimulator() .simulateLocationsAlongExistingRoute( - new SimulationOptions().speedMultiplier(speedMultiplier)); + new SimulationOptions().speedMultiplier((float) options.getDouble("speedMultiplier"))); + promise.resolve(true); } - @ReactMethod - public void stopLocationSimulation() { + @Override + public void stopLocationSimulation(Promise promise) { mNavigator.getSimulator().unsetUserLocation(); + promise.resolve(null); } - @ReactMethod - public void pauseLocationSimulation() { + @Override + public void pauseLocationSimulation(Promise promise) { mNavigator.getSimulator().pause(); + promise.resolve(null); } - @ReactMethod - public void resumeLocationSimulation() { + @Override + public void resumeLocationSimulation(Promise promise) { mNavigator.getSimulator().resume(); + promise.resolve(null); } - @ReactMethod + @Override public void setAbnormalTerminatingReportingEnabled(boolean isOn) { NavigationApi.setAbnormalTerminationReportingEnabled(isOn); } - @ReactMethod - public void setSpeedAlertOptions(@Nullable ReadableMap options) { + @Override + public void setAudioGuidanceType(double index, Promise promise) { + if (mNavigator == null) { + promise.reject(GMNJsErrors.NO_NAVIGATOR_ERROR_CODE, GMNJsErrors.NO_NAVIGATOR_ERROR_MESSAGE); + return; + } + + UiThreadUtil.runOnUiThread( + () -> { + mNavigator.setAudioGuidance( + GMNEnumTranslationUtil.getAudioGuidanceFromJsValue((int) index)); + promise.resolve(null); + }); + } + + @Override + public void setSpeedAlertOptions(@Nullable ReadableMap options, Promise promise) { if (options == null) { mNavigator.setSpeedAlertOptions(null); return; @@ -541,11 +538,11 @@ public void setSpeedAlertOptions(@Nullable ReadableMap options) { HashMap optionsMap = options.toHashMap(); float minorThresholdPercentage = - (float) CollectionUtil.getDouble("minorSpeedAlertPercentThreshold", optionsMap, -1); + (float) GMNCollectionUtil.getDouble("minorSpeedAlertPercentThreshold", optionsMap, -1); float majorThresholdPercentage = - (float) CollectionUtil.getDouble("majorSpeedAlertPercentThreshold", optionsMap, -1); + (float) GMNCollectionUtil.getDouble("majorSpeedAlertPercentThreshold", optionsMap, -1); float severityUpgradeDurationSeconds = - (float) CollectionUtil.getDouble("severityUpgradeDurationSeconds", optionsMap, -1); + (float) GMNCollectionUtil.getDouble("severityUpgradeDurationSeconds", optionsMap, -1); // The JS layer will validate the values before calling. SpeedAlertOptions alertOptions = @@ -561,22 +558,15 @@ public void setSpeedAlertOptions(@Nullable ReadableMap options) { }); } - @ReactMethod - public void setAudioGuidanceType(int jsValue) { - if (mNavigator == null) { - return; - } - - UiThreadUtil.runOnUiThread( - () -> { - mNavigator.setAudioGuidance(EnumTranslationUtil.getAudioGuidanceFromJsValue(jsValue)); - }); + @Override + public void setBackgroundLocationUpdatesEnabled(boolean isEnabled) { + // iOS only API method. } - @ReactMethod + @Override public void getCurrentTimeAndDistance(final Promise promise) { if (mNavigator == null) { - promise.reject(JsErrors.NO_NAVIGATOR_ERROR_CODE, JsErrors.NO_NAVIGATOR_ERROR_MESSAGE); + promise.reject(GMNJsErrors.NO_NAVIGATOR_ERROR_CODE, GMNJsErrors.NO_NAVIGATOR_ERROR_MESSAGE); return; } @@ -594,10 +584,10 @@ public void getCurrentTimeAndDistance(final Promise promise) { promise.resolve(map); } - @ReactMethod + @Override public void getCurrentRouteSegment(final Promise promise) { if (mNavigator == null) { - promise.reject(JsErrors.NO_NAVIGATOR_ERROR_CODE, JsErrors.NO_NAVIGATOR_ERROR_MESSAGE); + promise.reject(GMNJsErrors.NO_NAVIGATOR_ERROR_CODE, GMNJsErrors.NO_NAVIGATOR_ERROR_MESSAGE); return; } @@ -608,13 +598,13 @@ public void getCurrentRouteSegment(final Promise promise) { return; } - promise.resolve(ObjectTranslationUtil.getMapFromRouteSegment(routeSegment)); + promise.resolve(GMNObjectTranslationUtil.getMapFromRouteSegment(routeSegment)); } - @ReactMethod + @Override public void getRouteSegments(final Promise promise) { if (mNavigator == null) { - promise.reject(JsErrors.NO_NAVIGATOR_ERROR_CODE, JsErrors.NO_NAVIGATOR_ERROR_MESSAGE); + promise.reject(GMNJsErrors.NO_NAVIGATOR_ERROR_CODE, GMNJsErrors.NO_NAVIGATOR_ERROR_MESSAGE); return; } @@ -622,68 +612,53 @@ public void getRouteSegments(final Promise promise) { WritableArray arr = Arguments.createArray(); for (RouteSegment segment : routeSegmentList) { - arr.pushMap(ObjectTranslationUtil.getMapFromRouteSegment(segment)); + arr.pushMap(GMNObjectTranslationUtil.getMapFromRouteSegment(segment)); } promise.resolve(arr); } - @ReactMethod + @Override public void getTraveledPath(final Promise promise) { if (mNavigator == null) { - promise.reject(JsErrors.NO_NAVIGATOR_ERROR_CODE, JsErrors.NO_NAVIGATOR_ERROR_MESSAGE); + promise.reject(GMNJsErrors.NO_NAVIGATOR_ERROR_CODE, GMNJsErrors.NO_NAVIGATOR_ERROR_MESSAGE); return; } WritableArray arr = Arguments.createArray(); for (LatLng latLng : mNavigator.getTraveledRoute()) { - arr.pushMap(ObjectTranslationUtil.getMapFromLatLng(latLng)); + arr.pushMap(GMNObjectTranslationUtil.getMapFromLatLng(latLng)); } promise.resolve(arr); } - /** Send command to react native with string param. */ - private void sendCommandToReactNative(String functionName, String stringParam) { - WritableNativeArray params = new WritableNativeArray(); - - if (stringParam != null) { - params.pushString("" + stringParam); - } - sendCommandToReactNative(functionName, params); - } - - /** Send command to react native. */ - private void sendCommandToReactNative(String functionName, NativeArray params) { - ReactContext reactContext = getReactApplicationContext(); - - if (reactContext != null) { - CatalystInstance catalystInstance = reactContext.getCatalystInstance(); - catalystInstance.callFunction(Constants.NAV_JAVASCRIPT_FLAG, functionName, params); + @Override + public void simulateLocation(ReadableMap location, Promise promise) { + if (mNavigator == null) { + promise.reject(GMNJsErrors.NO_NAVIGATOR_ERROR_CODE, GMNJsErrors.NO_NAVIGATOR_ERROR_MESSAGE); + return; } - } - @ReactMethod - public void simulateLocation(ReadableMap location) { - if (mNavigator != null) { - HashMap locationMap = location.toHashMap(); - Double lat = CollectionUtil.getDouble("lat", locationMap, 0); - Double lng = CollectionUtil.getDouble("lng", locationMap, 0); - mNavigator.getSimulator().setUserLocation(new LatLng(lat, lng)); - } + HashMap locationMap = location.toHashMap(); + double lat = GMNCollectionUtil.getDouble("lat", locationMap, 0); + double lng = GMNCollectionUtil.getDouble("lng", locationMap, 0); + mNavigator.getSimulator().setUserLocation(new LatLng(lat, lng)); + promise.resolve(null); } - @ReactMethod - private void showTermsAndConditionsDialog() { - if (this.tocParamsMap == null) { + private void showTermsAndConditionsDialogAndInitializeNavigationApi(Promise promise) { + assert tocParamsMap != null; + Activity activity = getCurrentActivity(); + if (activity == null) { + promise.reject(GMNJsErrors.NO_ACTIVITY_ERROR_CODE, GMNJsErrors.NO_ACTIVITY_ERROR_MESSAGE); return; } - - String companyName = CollectionUtil.getString("companyName", this.tocParamsMap); - String title = CollectionUtil.getString("title", this.tocParamsMap); + String companyName = GMNCollectionUtil.getString("companyName", this.tocParamsMap); + String title = GMNCollectionUtil.getString("title", this.tocParamsMap); boolean showOnlyDisclaimer = - CollectionUtil.getBool("showOnlyDisclaimer", this.tocParamsMap, false); + GMNCollectionUtil.getBool("showOnlyDisclaimer", this.tocParamsMap, false); TermsAndConditionsCheckOption tosOption = showOnlyDisclaimer @@ -695,50 +670,54 @@ private void showTermsAndConditionsDialog() { companyName, title, null, - new OnTermsResponseListener() { - @Override - public void onTermsResponse(boolean areTermsAccepted) { - if (areTermsAccepted) { - initializeNavigationApi(); - } else { - onNavigationInitError(NavigationApi.ErrorCode.TERMS_NOT_ACCEPTED); - } + areTermsAccepted -> { + if (areTermsAccepted) { + initializeNavigationApi(promise); + } else { + promise.resolve(NavigationApi.ErrorCode.TERMS_NOT_ACCEPTED); } }, tosOption); } - @ReactMethod + @Override public void areTermsAccepted(final Promise promise) { promise.resolve(getTermsAccepted()); } public Boolean getTermsAccepted() { - return NavigationApi.areTermsAccepted(getCurrentActivity().getApplication()); + return NavigationApi.areTermsAccepted( + Objects.requireNonNull(getCurrentActivity()).getApplication()); } - @ReactMethod + @Override public void getNavSDKVersion(final Promise promise) { promise.resolve(NavigationApi.getNavSDKVersion()); } - @ReactMethod + @Override public void resetTermsAccepted() { - NavigationApi.resetTermsAccepted(getCurrentActivity().getApplication()); + NavigationApi.resetTermsAccepted(Objects.requireNonNull(getCurrentActivity()).getApplication()); } - @ReactMethod - public void startUpdatingLocation() { + @Override + public void startUpdatingLocation(Promise promise) { registerLocationListener(); mIsListeningRoadSnappedLocation = true; + promise.resolve(null); } - @ReactMethod - public void stopUpdatingLocation() { + private void stopUpdatingLocation() { mIsListeningRoadSnappedLocation = false; removeLocationListener(); } + @Override + public void stopUpdatingLocation(Promise promise) { + stopUpdatingLocation(); + promise.resolve(null); + } + private void registerLocationListener() { // Unregister existing location listener if available. removeLocationListener(); @@ -749,20 +728,16 @@ private void registerLocationListener() { @Override public void onLocationChanged(final Location location) { if (mIsListeningRoadSnappedLocation) { - WritableNativeArray params = new WritableNativeArray(); - params.pushMap(ObjectTranslationUtil.getMapFromLocation(location)); - - sendCommandToReactNative("onLocationChanged", params); + WritableMap locationMap = GMNObjectTranslationUtil.getMapFromLocation(location); + emitOnLocationChanged(locationMap); } } @Override public void onRawLocationUpdate(final Location location) { if (mIsListeningRoadSnappedLocation) { - WritableNativeArray params = new WritableNativeArray(); - params.pushMap(ObjectTranslationUtil.getMapFromLocation(location)); - - sendCommandToReactNative("onRawLocationChanged", params); + WritableMap locationMap = GMNObjectTranslationUtil.getMapFromLocation(location); + emitOnRawLocationChanged(locationMap); } } }; @@ -800,24 +775,25 @@ private void showNavInfo(NavInfo navInfo) { if (navInfo.getTimeToNextDestinationSeconds() != null) map.putInt("timeToNextDestinationSeconds", navInfo.getTimeToNextDestinationSeconds()); if (navInfo.getCurrentStep() != null) - map.putMap("currentStep", ObjectTranslationUtil.getMapFromStepInfo(navInfo.getCurrentStep())); + map.putMap( + "currentStep", GMNObjectTranslationUtil.getMapFromStepInfo(navInfo.getCurrentStep())); WritableArray remainingSteps = Arguments.createArray(); if (navInfo.getRemainingSteps() != null) { for (StepInfo info : navInfo.getRemainingSteps()) { - remainingSteps.pushMap(ObjectTranslationUtil.getMapFromStepInfo(info)); + remainingSteps.pushMap(GMNObjectTranslationUtil.getMapFromStepInfo(info)); } } map.putArray("getRemainingSteps", remainingSteps); - WritableNativeArray params = new WritableNativeArray(); - params.pushMap(map); - sendCommandToReactNative("onTurnByTurn", params); + emitOnTurnByTurn(map); } @Override public void logDebugInfo(String info) { - sendCommandToReactNative("logDebugInfo", info); + WritableMap map = Arguments.createMap(); + map.putString("message", info); + emitLogDebugInfo(map); } @Override @@ -841,8 +817,4 @@ public void onHostPause() {} @Override public void onHostDestroy() {} - - private interface IRouteStatusResult { - void onResult(Navigator.RouteStatus code); - } } diff --git a/android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavPackage.kt b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavPackage.kt new file mode 100644 index 00000000..38a60411 --- /dev/null +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavPackage.kt @@ -0,0 +1,84 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.maps.android.rn.navsdk + +import com.facebook.react.BaseReactPackage +import com.facebook.react.bridge.NativeModule +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.module.model.ReactModuleInfo +import com.facebook.react.module.model.ReactModuleInfoProvider +import com.facebook.react.uimanager.ViewManager +import java.util.HashMap + +class GMNNavPackage : BaseReactPackage() { + override fun createViewManagers(reactContext: ReactApplicationContext): List> { + val viewManagers: MutableList> = ArrayList() + viewManagers.add(GMNNavViewManager.getInstance(reactContext)) + return viewManagers + } + + override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? { + return when (name) { + GMNNavModule.NAME -> { + GMNNavModule.getInstance(reactContext, GMNNavViewManager.getInstance(reactContext)) + } + GMNNavAutoModule.NAME -> { + GMNNavAutoModule(reactContext) + } + GMNNavViewModule.NAME -> { + GMNNavViewModule(reactContext, GMNNavViewManager.getInstance(reactContext)) + } + else -> { + null + } + } + } + + override fun getReactModuleInfoProvider(): ReactModuleInfoProvider { + return ReactModuleInfoProvider { + val moduleInfos: MutableMap = HashMap() + moduleInfos[GMNNavModule.NAME] = + ReactModuleInfo( + name = GMNNavModule.NAME, + className = GMNNavModule.NAME, + canOverrideExistingModule = false, + needsEagerInit = false, + isCxxModule = false, + isTurboModule = true, + ) + moduleInfos[GMNNavAutoModule.NAME] = + ReactModuleInfo( + name = GMNNavAutoModule.NAME, + className = GMNNavAutoModule.NAME, + canOverrideExistingModule = false, + needsEagerInit = false, + isCxxModule = false, + isTurboModule = true, + ) + moduleInfos[GMNNavViewModule.NAME] = + ReactModuleInfo( + name = GMNNavViewModule.NAME, + className = GMNNavViewModule.NAME, + canOverrideExistingModule = false, + needsEagerInit = false, + isCxxModule = false, + isTurboModule = true, + ) + moduleInfos + } + } +} diff --git a/android/src/main/java/com/google/android/react/navsdk/NavViewFragment.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavViewFragment.java similarity index 50% rename from android/src/main/java/com/google/android/react/navsdk/NavViewFragment.java rename to android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavViewFragment.java index 57ad8548..4d0b1ca3 100644 --- a/android/src/main/java/com/google/android/react/navsdk/NavViewFragment.java +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavViewFragment.java @@ -11,7 +11,7 @@ * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.react.navsdk; +package com.google.maps.android.rn.navsdk; import android.annotation.SuppressLint; import android.os.Bundle; @@ -19,20 +19,16 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.WritableMap; import com.facebook.react.uimanager.UIManagerHelper; import com.facebook.react.uimanager.events.Event; import com.facebook.react.uimanager.events.EventDispatcher; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.OnMapReadyCallback; -import com.google.android.gms.maps.model.Circle; -import com.google.android.gms.maps.model.GroundOverlay; import com.google.android.gms.maps.model.LatLng; -import com.google.android.gms.maps.model.Marker; -import com.google.android.gms.maps.model.Polygon; -import com.google.android.gms.maps.model.Polyline; import com.google.android.libraries.navigation.NavigationView; +import com.google.android.libraries.navigation.PromptVisibilityChangedListener; import com.google.android.libraries.navigation.StylingOptions; import com.google.android.libraries.navigation.SupportNavigationFragment; @@ -40,58 +36,89 @@ * A fragment that displays a navigation view with a Google Map using SupportNavigationFragment. * This fragment's lifecycle is managed by NavViewManager. */ -public class NavViewFragment extends SupportNavigationFragment - implements INavViewFragment, INavigationViewCallback { +public class GMNNavViewFragment extends SupportNavigationFragment + implements IGMNNavViewFragment, IGMNNavigationViewCallback { private static final String TAG = "NavViewFragment"; - private MapViewController mMapViewController; + private GMNMapViewController mMapViewController; private GoogleMap mGoogleMap; private StylingOptions mStylingOptions; - private int viewTag; // React native view tag. - private ReactApplicationContext reactContext; + private final int viewId; // React native view tag. + private final ReactContext reactContext; - public NavViewFragment(ReactApplicationContext reactContext, int viewTag) { + public GMNNavViewFragment(ReactContext reactContext, int viewId) { this.reactContext = reactContext; - this.viewTag = viewTag; + this.viewId = viewId; } - private NavigationView.OnRecenterButtonClickedListener onRecenterButtonClickedListener = + private final NavigationView.OnRecenterButtonClickedListener onRecenterButtonClickedListener = new NavigationView.OnRecenterButtonClickedListener() { @Override public void onRecenterButtonClick() { - emitEvent("onRecenterButtonClick", null); + GMNNavViewFragment.this.onRecenterButtonClick(); } }; - private String style = ""; + private final PromptVisibilityChangedListener onPromptVisibilityChangedListener = + new PromptVisibilityChangedListener() { + @Override + public void onVisibilityChanged(boolean isVisible) { + GMNNavViewFragment.this.onPromptVisibilityChanged(isVisible); + } + }; + + private @Nullable Runnable mMapReadyListener; @SuppressLint("MissingPermission") @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - setNavigationUiEnabled(NavModule.getInstance().getNavigator() != null); + setNavigationUiEnabled( + GMNNavModule.hasInstance() && GMNNavModule.getInstance().getNavigator() != null); getMapAsync( new OnMapReadyCallback() { public void onMapReady(GoogleMap googleMap) { mGoogleMap = googleMap; - mMapViewController = new MapViewController(); + mMapViewController = new GMNMapViewController(); mMapViewController.initialize(googleMap, () -> requireActivity()); // Setup map listeners with the provided callback - mMapViewController.setupMapListeners(NavViewFragment.this); + mMapViewController.setupMapListeners(GMNNavViewFragment.this); - emitEvent("onMapReady", null); + setNavigationUiEnabled( + GMNNavModule.hasInstance() && GMNNavModule.getInstance().getNavigator() != null); + applyStylingOptions(); - setNavigationUiEnabled(NavModule.getInstance().getNavigator() != null); addOnRecenterButtonClickedListener(onRecenterButtonClickedListener); + addPromptVisibilityChangedListener(onPromptVisibilityChangedListener); + + GMNNavViewFragment.this.onMapReady(); } }); } - public MapViewController getMapController() { + @Override + public void setMapReadyListener(Runnable listener) { + if (mGoogleMap != null) { + listener.run(); + } else { + this.mMapReadyListener = listener; + } + } + + @Override + public void onMapReady() { + if (mMapReadyListener != null) { + mMapReadyListener.run(); + mMapReadyListener = null; + } + emitEvent("onMapReady", null); + } + + public GMNMapViewController getMapController() { return mMapViewController; } @@ -109,13 +136,14 @@ public void setStylingOptions(StylingOptions stylingOptions) { mStylingOptions = stylingOptions; } + @Override public void setNightModeOption(int jsValue) { - super.setForceNightMode(EnumTranslationUtil.getForceNightModeFromJsValue(jsValue)); + super.setForceNightMode(GMNEnumTranslationUtil.getForceNightModeFromJsValue(jsValue)); } @Override - public void onMapReady() { - emitEvent("onMapReady", null); + public void setReportIncidentButtonEnabled(boolean enabled) { + super.setReportIncidentButtonEnabled(enabled); } @Override @@ -124,38 +152,46 @@ public void onRecenterButtonClick() { } @Override - public void onMarkerClick(Marker marker) { - emitEvent("onMarkerClick", ObjectTranslationUtil.getMapFromMarker(marker)); + public void onPromptVisibilityChanged(boolean isVisible) { + WritableMap map = Arguments.createMap(); + map.putBoolean("visible", isVisible); + emitEvent("onPromptVisibilityChanged", map); } @Override - public void onPolylineClick(Polyline polyline) { - emitEvent("onPolylineClick", ObjectTranslationUtil.getMapFromPolyline(polyline)); + public void onMarkerClick(GMNMarker marker) { + emitEvent("onMarkerClick", GMNObjectTranslationUtil.getMapFromMarker(marker)); } @Override - public void onPolygonClick(Polygon polygon) { - emitEvent("onPolygonClick", ObjectTranslationUtil.getMapFromPolygon(polygon)); + public void onPolylineClick(GMNPolyline polyline) { + emitEvent("onPolylineClick", GMNObjectTranslationUtil.getMapFromPolyline(polyline)); } @Override - public void onCircleClick(Circle circle) { - emitEvent("onCircleClick", ObjectTranslationUtil.getMapFromCircle(circle)); + public void onPolygonClick(GMNPolygon polygon) { + emitEvent("onPolygonClick", GMNObjectTranslationUtil.getMapFromPolygon(polygon)); } @Override - public void onGroundOverlayClick(GroundOverlay groundOverlay) { - emitEvent("onGroundOverlayClick", ObjectTranslationUtil.getMapFromGroundOverlay(groundOverlay)); + public void onCircleClick(GMNCircle circle) { + emitEvent("onCircleClick", GMNObjectTranslationUtil.getMapFromCircle(circle)); } @Override - public void onMarkerInfoWindowTapped(Marker marker) { - emitEvent("onMarkerInfoWindowTapped", ObjectTranslationUtil.getMapFromMarker(marker)); + public void onGroundOverlayClick(GMNGroundOverlay groundOverlay) { + emitEvent( + "onGroundOverlayClick", GMNObjectTranslationUtil.getMapFromGroundOverlay(groundOverlay)); + } + + @Override + public void onMarkerInfoWindowTapped(GMNMarker marker) { + emitEvent("onMarkerInfoWindowTapped", GMNObjectTranslationUtil.getMapFromMarker(marker)); } @Override public void onMapClick(LatLng latLng) { - emitEvent("onMapClick", ObjectTranslationUtil.getMapFromLatLng(latLng)); + emitEvent("onMapClick", GMNObjectTranslationUtil.getMapFromLatLng(latLng)); } @Override @@ -174,33 +210,53 @@ public GoogleMap getGoogleMap() { return mGoogleMap; } + @Override + public void onMeasure(int measuredWidth, int measuredHeight) { + View view = getView(); + if (view != null) { + view.measure( + View.MeasureSpec.makeMeasureSpec(measuredWidth, View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(measuredHeight, View.MeasureSpec.EXACTLY)); + } + } + + @Override + public void onLayout(int width, int height) { + View view = getView(); + if (view != null) { + view.layout(0, 0, width, height); + } + } + private void cleanup() { removeOnRecenterButtonClickedListener(onRecenterButtonClickedListener); + removePromptVisibilityChangedListener(onPromptVisibilityChangedListener); } private void emitEvent(String eventName, @Nullable WritableMap data) { if (reactContext != null) { EventDispatcher dispatcher = - UIManagerHelper.getEventDispatcherForReactTag(reactContext, viewTag); + UIManagerHelper.getEventDispatcherForReactTag(reactContext, viewId); if (dispatcher != null) { int surfaceId = UIManagerHelper.getSurfaceId(reactContext); - dispatcher.dispatchEvent(new NavViewEvent(surfaceId, viewTag, eventName, data)); + dispatcher.dispatchEvent(new NavViewEvent(surfaceId, viewId, eventName, data)); } } } - public class NavViewEvent extends Event { - private String eventName; - private @Nullable WritableMap eventData; + public static class NavViewEvent extends Event { + private final String eventName; + private final @Nullable WritableMap eventData; public NavViewEvent( - int surfaceId, int viewTag, String eventName, @Nullable WritableMap eventData) { - super(surfaceId, viewTag); + int surfaceId, int viewId, String eventName, @Nullable WritableMap eventData) { + super(surfaceId, viewId); this.eventName = eventName; this.eventData = eventData; } + @NonNull @Override public String getEventName() { return eventName; diff --git a/android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavViewManager.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavViewManager.java new file mode 100644 index 00000000..a6f0fd81 --- /dev/null +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavViewManager.java @@ -0,0 +1,377 @@ +/** + * Copyright 2023 Google LLC + * + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + *

http://www.apache.org/licenses/LICENSE-2.0 + * + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.maps.android.rn.navsdk; + +import static com.google.maps.android.rn.navsdk.GMNEnumTranslationUtil.getMapViewTypeFromJsValue; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import com.facebook.react.bridge.Dynamic; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.module.annotations.ReactModule; +import com.facebook.react.touch.JSResponderHandler; +import com.facebook.react.uimanager.ReactStylesDiffMap; +import com.facebook.react.uimanager.SimpleViewManager; +import com.facebook.react.uimanager.StateWrapper; +import com.facebook.react.uimanager.ThemedReactContext; +import com.facebook.react.uimanager.ViewManagerDelegate; +import com.facebook.react.viewmanagers.NavViewManagerDelegate; +import com.facebook.react.viewmanagers.NavViewManagerInterface; +import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.maps.model.CameraPosition; +import java.lang.ref.WeakReference; +import java.util.HashMap; +import java.util.Map; + +// NavViewManager is responsible for managing both the regular map fragment as well as the +// navigation map view fragment. +@ReactModule(name = GMNNavViewManager.NAME) +public class GMNNavViewManager extends SimpleViewManager + implements NavViewManagerInterface { + private final NavViewManagerDelegate mDelegate = + new NavViewManagerDelegate<>(this); + + public static final String NAME = "NavView"; + + private static GMNNavViewManager instance; + + private final HashMap> fragmentMap = new HashMap<>(); + + private final ReactApplicationContext reactContext; + + public GMNNavViewManager(ReactApplicationContext reactContext) { + this.reactContext = reactContext; + } + + public static synchronized GMNNavViewManager getInstance(ReactApplicationContext reactContext) { + if (instance == null) { + instance = new GMNNavViewManager(reactContext); + } + return instance; + } + + public static synchronized GMNNavViewManager getInstance() { + return instance; + } + + @Nullable + @Override + protected ViewManagerDelegate getDelegate() { + return mDelegate; + } + + @Override + @NonNull + public String getName() { + return NAME; + } + + public @NonNull GMNMapViewLayout createView( + int reactTag, + @NonNull ThemedReactContext reactContext, + @Nullable ReactStylesDiffMap props, + @Nullable StateWrapper stateWrapper, + JSResponderHandler jsResponderHandler) { + return super.createView(reactTag, reactContext, props, stateWrapper, jsResponderHandler); + } + + /** Return a FrameLayout which will later hold the Fragment */ + @Override + @NonNull + public GMNMapViewLayout createViewInstance(@NonNull ThemedReactContext context) { + return new GMNMapViewLayout(context); + } + + public void onDropViewInstance(@NonNull GMNMapViewLayout view) { + super.onDropViewInstance(view); + fragmentMap.remove(view.getNativeID()); + } + + public IGMNNavViewFragment getNavFragmentForNativeID(int nativeID) { + IGMNMapViewFragment fragment = getFragmentForNativeID(nativeID); + + // Check if the fragment is an INavigationViewFragment + if (fragment instanceof IGMNNavViewFragment) { + return (IGMNNavViewFragment) fragment; + } else { + throw new IllegalStateException("The fragment is not a nav view fragment"); + } + } + + public IGMNNavViewFragment getNavFragmentForView(GMNMapViewLayout view) { + IGMNMapViewFragment fragment = view.getFragment(); + + // Check if the fragment is an INavigationViewFragment + if (fragment instanceof IGMNNavViewFragment) { + return (IGMNNavViewFragment) fragment; + } else { + throw new IllegalStateException("The fragment is not a nav view fragment"); + } + } + + public IGMNMapViewFragment getFragmentForNativeID(int nativeID) { + WeakReference weakReference = fragmentMap.get(nativeID); + if (weakReference == null || weakReference.get() == null) { + throw new IllegalStateException("Fragment not found for the provided viewId."); + } + return weakReference.get(); + } + + public IGMNMapViewFragment getFragmentForView(GMNMapViewLayout view) { + return view.getFragment(); + } + + public IGMNMapViewFragment getAnyFragment() { + if (fragmentMap.isEmpty()) { + return null; + } + // Return the first fragment found in the map's values collection. + return fragmentMap.values().iterator().next().get(); + } + + public void applyStylingOptions() { + for (WeakReference weakReference : fragmentMap.values()) { + if (weakReference.get() != null) { + weakReference.get().applyStylingOptions(); + } + } + } + + @Override + public Map getExportedCustomDirectEventTypeConstants() { + Map baseEventTypeConstants = super.getExportedCustomDirectEventTypeConstants(); + Map eventTypeConstants = + baseEventTypeConstants != null ? baseEventTypeConstants : new HashMap<>(); + + eventTypeConstants.putAll( + Map.of( + "topRecenterButtonClick", + Map.of("registrationName", "onRecenterButtonClick"), + "topPromptVisibilityChanged", + Map.of("registrationName", "onPromptVisibilityChanged"), + "topMapReady", + Map.of("registrationName", "onMapReady"), + "topMapClick", + Map.of("registrationName", "onMapClick"), + "topMarkerClick", + Map.of("registrationName", "onMarkerClick"), + "topPolylineClick", + Map.of("registrationName", "onPolylineClick"), + "topPolygonClick", + Map.of("registrationName", "onPolygonClick"), + "topCircleClick", + Map.of("registrationName", "onCircleClick"), + "topGroundOverlayClick", + Map.of("registrationName", "onGroundOverlayClick"), + "topMarkerInfoWindowTapped", + Map.of("registrationName", "onMarkerInfoWindowTapped"))); + + return eventTypeConstants; + } + + public GoogleMap getGoogleMap(int nativeID) { + try { + return getFragmentForNativeID(nativeID).getGoogleMap(); + } catch (Exception e) { + return null; + } + } + + @Override + public void setViewType(GMNMapViewLayout view, int value) { + GMNCustomTypes.MapViewType mapViewType = getMapViewTypeFromJsValue(value); + view.setMapViewType(mapViewType); + } + + @Override + public void setNativeID(GMNMapViewLayout view, @Nullable String value) { + assert value != null; + view.setNativeID(Integer.parseInt(value)); + super.setNativeId(view, value); + } + + @Override + public void setNavigationUIEnabled(GMNMapViewLayout view, @Nullable Boolean value) { + view.setNavigationUIEnabled(value); + } + + @Override + public void setMapType(GMNMapViewLayout view, int value) { + view.setMapType(value); + } + + @Override + public void setMapPadding(GMNMapViewLayout view, @Nullable ReadableMap value) { + view.setMapPadding(value); + } + + @Override + public void setTripProgressBarEnabled(GMNMapViewLayout view, boolean value) { + view.setTripProgressBarEnabled(value); + } + + @Override + public void setTrafficIncidentsCardEnabled(GMNMapViewLayout view, boolean value) { + view.setTrafficIncidentsCardEnabled(value); + } + + @Override + public void setHeaderEnabled(GMNMapViewLayout view, boolean value) { + view.setHeaderEnabled(value); + } + + @Override + public void setFooterEnabled(GMNMapViewLayout view, boolean value) { + view.setFooterEnabled(value); + } + + @Override + public void setSpeedometerEnabled(GMNMapViewLayout view, boolean value) { + view.setSpeedometerEnabled(value); + } + + @Override + public void setSpeedLimitIconEnabled(GMNMapViewLayout view, boolean value) { + view.setSpeedLimitIconEnabled(value); + } + + @Override + public void setRecenterButtonEnabled(GMNMapViewLayout view, boolean value) { + view.setRecenterButtonEnabled(value); + } + + @Override + public void setNavigationViewStylingOptions(GMNMapViewLayout view, Dynamic value) { + view.setNavigationViewStylingOptions(value.isNull() ? null : value.asMap()); + } + + @Override + public void setNightMode(GMNMapViewLayout view, int value) { + view.setNightMode(value); + } + + @Override + public void setFollowingPerspective(GMNMapViewLayout view, int value) { + view.setFollowingPerspective(value); + } + + @Override + public void setMapStyle(GMNMapViewLayout view, @Nullable String value) { + view.setMapStyle(value); + } + + @Override + public void setMapId(GMNMapViewLayout view, @Nullable String value) { + view.setMapId(value); + } + + @Override + public void setMapToolbarEnabled(GMNMapViewLayout view, boolean value) { + view.setMapToolbarEnabled(value); + } + + @Override + public void setIndoorEnabled(GMNMapViewLayout view, boolean value) { + view.setIndoorEnabled(value); + } + + @Override + public void setTrafficEnabled(GMNMapViewLayout view, boolean value) { + view.setTrafficEnabled(value); + } + + @Override + public void setCompassEnabled(GMNMapViewLayout view, boolean value) { + view.setCompassEnabled(value); + } + + @Override + public void setMyLocationButtonEnabled(GMNMapViewLayout view, boolean value) { + view.setMyLocationButtonEnabled(value); + } + + @Override + public void setMyLocationEnabled(GMNMapViewLayout view, boolean value) { + view.setMyLocationEnabled(value); + } + + @Override + public void setRotateGesturesEnabled(GMNMapViewLayout view, boolean value) { + view.setRotateGesturesEnabled(value); + } + + @Override + public void setScrollGesturesEnabled(GMNMapViewLayout view, boolean value) { + view.setScrollGesturesEnabled(value); + } + + @Override + public void setScrollGesturesEnabledDuringRotateOrZoom(GMNMapViewLayout view, boolean value) { + view.setScrollGesturesEnabledDuringRotateOrZoom(value); + } + + @Override + public void setTiltGesturesEnabled(GMNMapViewLayout view, boolean value) { + view.setTiltGesturesEnabled(value); + } + + @Override + public void setZoomControlsEnabled(GMNMapViewLayout view, boolean value) { + view.setZoomControlsEnabled(value); + } + + @Override + public void setZoomGesturesEnabled(GMNMapViewLayout view, boolean value) { + view.setZoomGesturesEnabled(value); + } + + @Override + public void setBuildingsEnabled(GMNMapViewLayout view, boolean value) { + view.setBuildingsEnabled(value); + } + + @Override + public void setReportIncidentButtonEnabled(GMNMapViewLayout view, boolean value) { + view.setReportIncidentButtonEnabled(value); + } + + @Override + public void setMinZoomLevel(GMNMapViewLayout view, @Nullable Float value) { + view.setMinZoomLevel(value); + } + + @Override + public void setMaxZoomLevel(GMNMapViewLayout view, @Nullable Float value) { + view.setMaxZoomLevel(value); + } + + @Override + public void setInitialCameraPosition( + GMNMapViewLayout view, @Nullable ReadableMap cameraPositionMap) { + if (cameraPositionMap == null) { + view.setInitialCameraPosition(null); + } else { + CameraPosition cameraPos = + GMNObjectTranslationUtil.getCameraPositionFromMap(cameraPositionMap.toHashMap()); + view.setInitialCameraPosition(cameraPos); + } + } + + public void registerFragment(Integer nativeID, IGMNMapViewFragment fragment) { + if (!fragmentMap.containsKey(nativeID)) { + fragmentMap.put(nativeID, new WeakReference(fragment)); + } + } +} diff --git a/android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavViewModule.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavViewModule.java new file mode 100644 index 00000000..a42a2f7f --- /dev/null +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNNavViewModule.java @@ -0,0 +1,378 @@ +/** + * Copyright 2023 Google LLC + * + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + *

http://www.apache.org/licenses/LICENSE-2.0 + * + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.maps.android.rn.navsdk; + +import android.location.Location; +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.UiThreadUtil; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.module.annotations.ReactModule; +import com.google.android.gms.maps.UiSettings; +import com.google.android.gms.maps.model.CameraPosition; +import com.google.android.gms.maps.model.LatLng; + +/** + * This exposes a series of methods that can be called diretly from the React Native code. They have + * been implemented using promises as it's not recommended for them to be synchronous. + */ +@ReactModule(name = GMNNavViewModule.NAME) +public class GMNNavViewModule extends NativeNavViewModuleSpec { + + private final GMNNavViewManager mNavViewManager; + + public GMNNavViewModule(ReactApplicationContext reactContext, GMNNavViewManager navViewManager) { + super(reactContext); + mNavViewManager = navViewManager; + } + + @Override + public void getCameraPosition(double nativeID, final Promise promise) { + UiThreadUtil.runOnUiThread( + () -> { + if (mNavViewManager.getGoogleMap((int) nativeID) == null) { + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); + return; + } + + CameraPosition cp = mNavViewManager.getGoogleMap((int) nativeID).getCameraPosition(); + + LatLng target = cp.target; + WritableMap map = Arguments.createMap(); + map.putDouble("bearing", cp.bearing); + map.putDouble("tilt", cp.tilt); + map.putDouble("zoom", cp.zoom); + map.putMap("target", GMNObjectTranslationUtil.getMapFromLatLng(target)); + + promise.resolve(map); + }); + } + + @Override + public void getMyLocation(double nativeID, final Promise promise) { + UiThreadUtil.runOnUiThread( + () -> { + if (mNavViewManager.getGoogleMap((int) nativeID) == null) { + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); + return; + } + + try { + Location location = mNavViewManager.getGoogleMap((int) nativeID).getMyLocation(); + promise.resolve(GMNObjectTranslationUtil.getMapFromLocation(location)); + } catch (Exception e) { + promise.resolve(null); + } + }); + } + + @Override + public void getUiSettings(double nativeID, final Promise promise) { + UiThreadUtil.runOnUiThread( + () -> { + if (mNavViewManager.getGoogleMap((int) nativeID) == null) { + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); + return; + } + + UiSettings settings = mNavViewManager.getGoogleMap((int) nativeID).getUiSettings(); + + if (settings == null) { + promise.resolve(null); + return; + } + + WritableMap map = Arguments.createMap(); + map.putBoolean("isCompassEnabled", settings.isCompassEnabled()); + map.putBoolean("isMapToolbarEnabled", settings.isMapToolbarEnabled()); + map.putBoolean("isIndoorLevelPickerEnabled", settings.isIndoorLevelPickerEnabled()); + map.putBoolean("isRotateGesturesEnabled", settings.isRotateGesturesEnabled()); + map.putBoolean("isScrollGesturesEnabled", settings.isScrollGesturesEnabled()); + map.putBoolean( + "isScrollGesturesEnabledDuringRotateOrZoom", + settings.isScrollGesturesEnabledDuringRotateOrZoom()); + map.putBoolean("isTiltGesturesEnabled", settings.isTiltGesturesEnabled()); + map.putBoolean("isZoomControlsEnabled", settings.isZoomControlsEnabled()); + map.putBoolean("isZoomGesturesEnabled", settings.isZoomGesturesEnabled()); + + promise.resolve(map); + }); + } + + @Override + public void isMyLocationEnabled(double nativeID, final Promise promise) { + UiThreadUtil.runOnUiThread( + () -> { + if (mNavViewManager.getGoogleMap((int) nativeID) == null) { + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); + return; + } + + promise.resolve(mNavViewManager.getGoogleMap((int) nativeID).isMyLocationEnabled()); + }); + } + + // Generic error handler for promise-based view method calls. + private void handleError(Promise promise, Exception e) { + String code = GMNJsErrors.UNKNOWN_NATIVE_ERROR_CODE; + + if (e instanceof IllegalStateException) { + String msg = e.getMessage(); + if (msg != null) { + if (msg.contains("Fragment not found for the provided viewId.")) { + code = GMNJsErrors.VIEW_NOT_FOUND_ERROR_CODE; + } + } + } + promise.reject(code, e); + } + + @Override + public void showRouteOverview(double viewId, Promise promise) { + UiThreadUtil.runOnUiThread( + () -> { + try { + mNavViewManager.getNavFragmentForNativeID((int) viewId).showRouteOverview(); + promise.resolve(null); + } catch (Exception e) { + handleError(promise, e); + } + }); + } + + @Override + public void clearMapView(double viewId, Promise promise) { + UiThreadUtil.runOnUiThread( + () -> { + try { + mNavViewManager.getFragmentForNativeID((int) viewId).getGoogleMap().clear(); + promise.resolve(null); + } catch (Exception e) { + handleError(promise, e); + } + }); + } + + @Override + public void removeMarker(double viewId, String id, Promise promise) { + UiThreadUtil.runOnUiThread( + () -> { + try { + mNavViewManager + .getFragmentForNativeID((int) viewId) + .getMapController() + .removeMarker(id); + promise.resolve(null); + } catch (Exception e) { + handleError(promise, e); + } + }); + } + + @Override + public void removePolyline(double viewId, String id, Promise promise) { + UiThreadUtil.runOnUiThread( + () -> { + try { + mNavViewManager + .getFragmentForNativeID((int) viewId) + .getMapController() + .removePolyline(id); + promise.resolve(null); + } catch (Exception e) { + handleError(promise, e); + } + }); + } + + @Override + public void removePolygon(double viewId, String id, Promise promise) { + UiThreadUtil.runOnUiThread( + () -> { + try { + mNavViewManager + .getFragmentForNativeID((int) viewId) + .getMapController() + .removePolygon(id); + promise.resolve(null); + } catch (Exception e) { + handleError(promise, e); + } + }); + } + + @Override + public void removeCircle(double viewId, String id, Promise promise) { + UiThreadUtil.runOnUiThread( + () -> { + try { + mNavViewManager + .getFragmentForNativeID((int) viewId) + .getMapController() + .removeCircle(id); + promise.resolve(null); + } catch (Exception e) { + handleError(promise, e); + } + }); + } + + @Override + public void removeGroundOverlay(double viewId, String id, Promise promise) { + UiThreadUtil.runOnUiThread( + () -> { + try { + mNavViewManager + .getFragmentForNativeID((int) viewId) + .getMapController() + .removeGroundOverlay(id); + promise.resolve(null); + } catch (Exception e) { + handleError(promise, e); + } + }); + } + + @Override + public void setZoomLevel(double viewId, double level, Promise promise) { + UiThreadUtil.runOnUiThread( + () -> { + try { + mNavViewManager + .getFragmentForNativeID((int) viewId) + .getMapController() + .setZoomLevel((int) level); + promise.resolve(null); + } catch (Exception e) { + handleError(promise, e); + } + }); + } + + @Override + public void moveCamera(double nativeID, ReadableMap cameraPositionMap, Promise promise) { + UiThreadUtil.runOnUiThread( + () -> { + try { + CameraPosition cameraPos = + GMNObjectTranslationUtil.getCameraPositionFromMap(cameraPositionMap.toHashMap()); + mNavViewManager + .getFragmentForNativeID((int) nativeID) + .getMapController() + .moveCamera(cameraPos); + promise.resolve(null); + } catch (Exception e) { + handleError(promise, e); + } + }); + } + + @Override + public void addMarker(double nativeID, ReadableMap markerOptionsMap, final Promise promise) { + UiThreadUtil.runOnUiThread( + () -> { + if (mNavViewManager.getGoogleMap((int) nativeID) == null) { + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); + return; + } + GMNMarker marker = + mNavViewManager + .getFragmentForNativeID((int) nativeID) + .getMapController() + .addMarker(markerOptionsMap.toHashMap()); + + promise.resolve(GMNObjectTranslationUtil.getMapFromMarker(marker)); + }); + } + + @Override + public void addPolyline(double nativeID, ReadableMap polylineOptionsMap, final Promise promise) { + UiThreadUtil.runOnUiThread( + () -> { + if (mNavViewManager.getGoogleMap((int) nativeID) == null) { + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); + return; + } + GMNPolyline polyline = + mNavViewManager + .getFragmentForNativeID((int) nativeID) + .getMapController() + .addPolyline(polylineOptionsMap.toHashMap()); + + promise.resolve(GMNObjectTranslationUtil.getMapFromPolyline(polyline)); + }); + } + + @Override + public void addPolygon(double nativeID, ReadableMap polygonOptionsMap, final Promise promise) { + UiThreadUtil.runOnUiThread( + () -> { + if (mNavViewManager.getGoogleMap((int) nativeID) == null) { + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); + return; + } + GMNPolygon polygon = + mNavViewManager + .getFragmentForNativeID((int) nativeID) + .getMapController() + .addPolygon(polygonOptionsMap.toHashMap()); + + promise.resolve(GMNObjectTranslationUtil.getMapFromPolygon(polygon)); + }); + } + + @Override + public void addCircle(double nativeID, ReadableMap circleOptionsMap, final Promise promise) { + UiThreadUtil.runOnUiThread( + () -> { + if (mNavViewManager.getGoogleMap((int) nativeID) == null) { + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); + return; + } + GMNCircle circle = + mNavViewManager + .getFragmentForNativeID((int) nativeID) + .getMapController() + .addCircle(circleOptionsMap.toHashMap()); + + promise.resolve(GMNObjectTranslationUtil.getMapFromCircle(circle)); + }); + } + + @Override + public void addGroundOverlay( + double nativeID, ReadableMap overlayOptionsMap, final Promise promise) { + UiThreadUtil.runOnUiThread( + () -> { + if (mNavViewManager.getGoogleMap((int) nativeID) == null) { + promise.reject(GMNJsErrors.NO_MAP_ERROR_CODE, GMNJsErrors.NO_MAP_ERROR_MESSAGE); + return; + } + GMNGroundOverlay overlay = + mNavViewManager + .getFragmentForNativeID((int) nativeID) + .getMapController() + .addGroundOverlay(overlayOptionsMap.toHashMap()); + + promise.resolve(GMNObjectTranslationUtil.getMapFromGroundOverlay(overlay)); + }); + } + + @Override + public boolean canOverrideExistingModule() { + return true; + } +} diff --git a/android/src/main/java/com/google/android/react/navsdk/ObjectTranslationUtil.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNObjectTranslationUtil.java similarity index 69% rename from android/src/main/java/com/google/android/react/navsdk/ObjectTranslationUtil.java rename to android/src/main/java/com/google/maps/android/rn/navsdk/GMNObjectTranslationUtil.java index 0c5bc8e0..06f7fef7 100644 --- a/android/src/main/java/com/google/android/react/navsdk/ObjectTranslationUtil.java +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNObjectTranslationUtil.java @@ -11,13 +11,14 @@ * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.react.navsdk; +package com.google.maps.android.rn.navsdk; import android.location.Location; import android.os.Build; import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.WritableArray; import com.facebook.react.bridge.WritableMap; +import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.Circle; import com.google.android.gms.maps.model.GroundOverlay; import com.google.android.gms.maps.model.LatLng; @@ -34,26 +35,21 @@ import java.util.List; import java.util.Map; -public class ObjectTranslationUtil { +public class GMNObjectTranslationUtil { public static WritableMap getMapFromRouteSegment(RouteSegment routeSegment) { WritableMap parentMap = Arguments.createMap(); - // Destination latLng - WritableMap mapDestLatLng = Arguments.createMap(); parentMap.putMap("destinationLatLng", getMapFromLatLng(routeSegment.getDestinationLatLng())); - // Destination waypoint parentMap.putMap( "destinationWaypoint", getMapFromWaypoint(routeSegment.getDestinationWaypoint())); - // Lat Lngs WritableArray latLngArr = Arguments.createArray(); for (LatLng latLng : routeSegment.getLatLngs()) { latLngArr.pushMap(getMapFromLatLng(latLng)); } parentMap.putArray("segmentLatLngList", latLngArr); - // Traffic data WritableArray stretchRenderingDataArr = Arguments.createArray(); for (NavigationRoadStretchRenderingData data : routeSegment.getTrafficData().getRoadStretchRenderingDataList()) { @@ -106,55 +102,56 @@ public static WritableMap getMapFromStepInfo(StepInfo stepInfo) { return map; } - public static DisplayOptions getDisplayOptionsFromMap(Map map) { + public static DisplayOptions getDisplayOptionsFromMap(Map map) { DisplayOptions options = new DisplayOptions(); if (map.containsKey("showDestinationMarkers")) { - options.hideDestinationMarkers(!CollectionUtil.getBool("showDestinationMarkers", map, true)); + options.hideDestinationMarkers( + !GMNCollectionUtil.getBool("showDestinationMarkers", map, true)); } if (map.containsKey("showStopSigns")) { - options.showStopSigns(CollectionUtil.getBool("showStopSigns", map, false)); + options.showStopSigns(GMNCollectionUtil.getBool("showStopSigns", map, false)); } if (map.containsKey("showTrafficLights")) { - options.showTrafficLights(CollectionUtil.getBool("showTrafficLights", map, false)); + options.showTrafficLights(GMNCollectionUtil.getBool("showTrafficLights", map, false)); } return options; } - public static RoutingOptions getRoutingOptionsFromMap(Map map) { + public static RoutingOptions getRoutingOptionsFromMap(Map map) { RoutingOptions options = new RoutingOptions(); if (map.containsKey("avoidTolls")) { - options.avoidTolls(CollectionUtil.getBool("avoidTolls", map, false)); + options.avoidTolls(GMNCollectionUtil.getBool("avoidTolls", map, false)); } if (map.containsKey("avoidHighways")) { - options.avoidHighways(CollectionUtil.getBool("avoidHighways", map, false)); + options.avoidHighways(GMNCollectionUtil.getBool("avoidHighways", map, false)); } if (map.containsKey("avoidFerries")) { - options.avoidFerries(CollectionUtil.getBool("avoidFerries", map, true)); + options.avoidFerries(GMNCollectionUtil.getBool("avoidFerries", map, true)); } if (map.containsKey("travelMode")) { options.travelMode( - CollectionUtil.getInt("travelMode", map, RoutingOptions.TravelMode.DRIVING)); + GMNCollectionUtil.getInt("travelMode", map, RoutingOptions.TravelMode.DRIVING)); } if (map.containsKey("routingStrategy")) { options.routingStrategy( - CollectionUtil.getInt( + GMNCollectionUtil.getInt( "routingStrategy", map, RoutingOptions.RoutingStrategy.DEFAULT_BEST)); } if (map.containsKey("alternateRoutesStrategy")) { - int routesStrategyJsValue = CollectionUtil.getInt("alternateRoutesStrategy", map, -1); + int routesStrategyJsValue = GMNCollectionUtil.getInt("alternateRoutesStrategy", map, -1); AlternateRoutesStrategy routeStrategy = - EnumTranslationUtil.getAlternateRoutesStrategyFromJsValue(routesStrategyJsValue); + GMNEnumTranslationUtil.getAlternateRoutesStrategyFromJsValue(routesStrategyJsValue); options.alternateRoutesStrategy(routeStrategy); } @@ -162,13 +159,28 @@ public static RoutingOptions getRoutingOptionsFromMap(Map map) { return options; } - public static LatLng getLatLngFromMap(Map map) { - if (map.get(Constants.LAT_FIELD_KEY) == null || map.get(Constants.LNG_FIELD_KEY) == null) { + public static LatLng getLatLngFromMap(Map map) { + if (map.get(GMNConstants.LAT_FIELD_KEY) == null + || map.get(GMNConstants.LNG_FIELD_KEY) == null) { return null; } return new LatLng( - (Double) map.get(Constants.LAT_FIELD_KEY), (Double) map.get(Constants.LNG_FIELD_KEY)); + (Double) map.get(GMNConstants.LAT_FIELD_KEY), (Double) map.get(GMNConstants.LNG_FIELD_KEY)); + } + + public static CameraPosition getCameraPositionFromMap(Map map) { + float zoom = (float) GMNCollectionUtil.getDouble("zoom", map, 0); + float tilt = (float) GMNCollectionUtil.getDouble("tilt", map, 0); + float bearing = (float) GMNCollectionUtil.getDouble("bearing", map, 0); + return new CameraPosition.Builder() + .target( + getLatLngFromMap((Map) map.get("target"))) // Set the target location + .zoom(zoom) // Set the desired zoom level + .tilt(tilt) // Set the desired tilt angle (0 for straight down, 90 for straight + // up) + .bearing(bearing) // Set the desired bearing (rotation angle in degrees) + .build(); } public static WritableMap getMapFromLocation(Location location) { @@ -199,23 +211,26 @@ public static WritableMap getMapFromLocation(Location location) { return map; } - public static WritableMap getMapFromGroundOverlay(GroundOverlay overlay) { + public static WritableMap getMapFromGroundOverlay(GMNGroundOverlay gmnOverlay) { + GroundOverlay overlay = gmnOverlay.groundOverlay(); + String rnId = gmnOverlay.rnId(); + WritableMap map = Arguments.createMap(); - map.putMap("position", ObjectTranslationUtil.getMapFromLatLng(overlay.getPosition())); + map.putMap("position", GMNObjectTranslationUtil.getMapFromLatLng(overlay.getPosition())); WritableMap mapBounds = Arguments.createMap(); mapBounds.putMap( - "northEast", ObjectTranslationUtil.getMapFromLatLng(overlay.getBounds().northeast)); + "northEast", GMNObjectTranslationUtil.getMapFromLatLng(overlay.getBounds().northeast)); mapBounds.putMap( - "southWest", ObjectTranslationUtil.getMapFromLatLng(overlay.getBounds().southwest)); + "southWest", GMNObjectTranslationUtil.getMapFromLatLng(overlay.getBounds().southwest)); mapBounds.putMap( - "center", ObjectTranslationUtil.getMapFromLatLng(overlay.getBounds().getCenter())); + "center", GMNObjectTranslationUtil.getMapFromLatLng(overlay.getBounds().getCenter())); map.putMap("bounds", mapBounds); - map.putString("id", overlay.getId()); + map.putString("id", rnId != null ? rnId : overlay.getId()); map.putDouble("height", overlay.getHeight()); map.putDouble("width", overlay.getWidth()); map.putDouble("bearing", overlay.getBearing()); @@ -225,11 +240,13 @@ public static WritableMap getMapFromGroundOverlay(GroundOverlay overlay) { return map; } - public static WritableMap getMapFromMarker(Marker marker) { - WritableMap map = Arguments.createMap(); + public static WritableMap getMapFromMarker(GMNMarker gmnMarker) { + Marker marker = gmnMarker.marker(); + String rnId = gmnMarker.rnId(); + WritableMap map = Arguments.createMap(); map.putMap("position", getMapFromLatLng(marker.getPosition())); - map.putString("id", marker.getId()); + map.putString("id", rnId != null ? rnId : marker.getId()); map.putString("title", marker.getTitle()); map.putDouble("alpha", marker.getAlpha()); map.putDouble("rotation", marker.getRotation()); @@ -239,11 +256,14 @@ public static WritableMap getMapFromMarker(Marker marker) { return map; } - public static WritableMap getMapFromCircle(Circle circle) { + public static WritableMap getMapFromCircle(GMNCircle gmnCircle) { + Circle circle = gmnCircle.circle(); + String rnId = gmnCircle.rnId(); + WritableMap map = Arguments.createMap(); - map.putMap("center", ObjectTranslationUtil.getMapFromLatLng(circle.getCenter())); + map.putMap("center", GMNObjectTranslationUtil.getMapFromLatLng(circle.getCenter())); - map.putString("id", circle.getId()); + map.putString("id", rnId != null ? rnId : circle.getId()); map.putInt("fillColor", circle.getFillColor()); map.putDouble("strokeWidth", circle.getStrokeWidth()); map.putInt("strokeColor", circle.getStrokeColor()); @@ -253,16 +273,19 @@ public static WritableMap getMapFromCircle(Circle circle) { return map; } - public static WritableMap getMapFromPolyline(Polyline polyline) { + public static WritableMap getMapFromPolyline(GMNPolyline gmnPolyline) { + Polyline polyline = gmnPolyline.polyline(); + String rnId = gmnPolyline.rnId(); + WritableMap map = Arguments.createMap(); WritableArray pointsArr = Arguments.createArray(); for (LatLng point : polyline.getPoints()) { - pointsArr.pushMap(ObjectTranslationUtil.getMapFromLatLng(point)); + pointsArr.pushMap(GMNObjectTranslationUtil.getMapFromLatLng(point)); } map.putArray("points", pointsArr); - map.putString("id", polyline.getId()); + map.putString("id", rnId != null ? rnId : polyline.getId()); map.putInt("color", polyline.getColor()); map.putDouble("width", polyline.getWidth()); map.putInt("jointType", polyline.getJointType()); @@ -271,12 +294,14 @@ public static WritableMap getMapFromPolyline(Polyline polyline) { return map; } - public static WritableMap getMapFromPolygon(Polygon polygon) { + public static WritableMap getMapFromPolygon(GMNPolygon gmnPolygon) { + Polygon polygon = gmnPolygon.polygon(); + String rnId = gmnPolygon.rnId(); WritableMap map = Arguments.createMap(); WritableArray pointsArr = Arguments.createArray(); for (LatLng point : polygon.getPoints()) { - pointsArr.pushMap(ObjectTranslationUtil.getMapFromLatLng(point)); + pointsArr.pushMap(GMNObjectTranslationUtil.getMapFromLatLng(point)); } map.putArray("points", pointsArr); @@ -286,14 +311,14 @@ public static WritableMap getMapFromPolygon(Polygon polygon) { WritableArray holeArr = Arguments.createArray(); for (LatLng point : holes) { - holesArr.pushMap(ObjectTranslationUtil.getMapFromLatLng(point)); + holesArr.pushMap(GMNObjectTranslationUtil.getMapFromLatLng(point)); } holesArr.pushArray(holeArr); } map.putArray("holes", holesArr); - map.putString("id", polygon.getId()); + map.putString("id", rnId != null ? rnId : polygon.getId()); map.putInt("fillColor", polygon.getFillColor()); map.putDouble("strokeWidth", polygon.getStrokeWidth()); map.putInt("strokeColor", polygon.getStrokeColor()); diff --git a/android/src/main/java/com/google/maps/android/rn/navsdk/GMNPolygon.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNPolygon.java new file mode 100644 index 00000000..cb5af0ec --- /dev/null +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNPolygon.java @@ -0,0 +1,23 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.maps.android.rn.navsdk; + +import androidx.annotation.Nullable; +import com.google.android.gms.maps.model.Polygon; + +/** Immutable wrapper for a Google Maps Polygon and an optional RN ID. */ +public record GMNPolygon(Polygon polygon, @Nullable String rnId) {} diff --git a/android/src/main/java/com/google/maps/android/rn/navsdk/GMNPolyline.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNPolyline.java new file mode 100644 index 00000000..585c2943 --- /dev/null +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNPolyline.java @@ -0,0 +1,23 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.maps.android.rn.navsdk; + +import androidx.annotation.Nullable; +import com.google.android.gms.maps.model.Polyline; + +/** Immutable wrapper for a Google Maps Polyline and an optional RN ID. */ +public record GMNPolyline(Polyline polyline, @Nullable String rnId) {} diff --git a/android/src/main/java/com/google/android/react/navsdk/StylingOptionsBuilder.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNStylingOptionsBuilder.java similarity index 84% rename from android/src/main/java/com/google/android/react/navsdk/StylingOptionsBuilder.java rename to android/src/main/java/com/google/maps/android/rn/navsdk/GMNStylingOptionsBuilder.java index 7ff59d51..9f113484 100644 --- a/android/src/main/java/com/google/android/react/navsdk/StylingOptionsBuilder.java +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNStylingOptionsBuilder.java @@ -11,16 +11,16 @@ * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.react.navsdk; +package com.google.maps.android.rn.navsdk; -import android.graphics.Color; import com.google.android.libraries.navigation.StylingOptions; import java.util.Map; +import java.util.Objects; -public class StylingOptionsBuilder { +public class GMNStylingOptionsBuilder { private StylingOptions mStylingOptions; - private StylingOptionsBuilder(Builder builder) { + private GMNStylingOptionsBuilder(Builder builder) { this.mStylingOptions = builder.mStylingOptions; } @@ -33,7 +33,9 @@ public Builder(Map map) { } private int parseColor(String color, Map map) { - return Color.parseColor(CollectionUtil.getString(color, map)); + return GMNColorUtil.colorFromHexString( + Objects.requireNonNull(GMNCollectionUtil.getString(color, map))) + .toArgb(); } public StylingOptions build() { @@ -73,19 +75,20 @@ public StylingOptions build() { parseColor("headerGuidanceRecommendedLaneColor", stylingOptions)); if (stylingOptions.containsKey("headerNextStepTextSize")) mStylingOptions.headerNextStepTextSize( - Float.parseFloat(CollectionUtil.getString("headerNextStepTextSize", stylingOptions))); + Float.parseFloat( + GMNCollectionUtil.getString("headerNextStepTextSize", stylingOptions))); if (stylingOptions.containsKey("headerDistanceValueTextSize")) mStylingOptions.headerDistanceValueTextSize( Float.parseFloat( - CollectionUtil.getString("headerDistanceValueTextSize", stylingOptions))); + GMNCollectionUtil.getString("headerDistanceValueTextSize", stylingOptions))); if (stylingOptions.containsKey("headerDistanceUnitsTextSize")) mStylingOptions.headerDistanceUnitsTextSize( Float.parseFloat( - CollectionUtil.getString("headerDistanceUnitsTextSize", stylingOptions))); + GMNCollectionUtil.getString("headerDistanceUnitsTextSize", stylingOptions))); if (stylingOptions.containsKey("headerInstructionsFirstRowTextSize")) { mStylingOptions.headerInstructionsFirstRowTextSize( Float.parseFloat( - CollectionUtil.getString("headerInstructionsFirstRowTextSize", stylingOptions))); + GMNCollectionUtil.getString("headerInstructionsFirstRowTextSize", stylingOptions))); } if (stylingOptions.containsKey("headerInstructionsSecondRowTextSize")) mStylingOptions.headerInstructionsSecondRowTextSize(20f); diff --git a/android/src/main/java/com/google/maps/android/rn/navsdk/GMNViewProps.java b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNViewProps.java new file mode 100644 index 00000000..407bbf30 --- /dev/null +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/GMNViewProps.java @@ -0,0 +1,128 @@ +/** + * Copyright 2025 Google LLC + * + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + *

http://www.apache.org/licenses/LICENSE-2.0 + * + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.maps.android.rn.navsdk; + +import androidx.annotation.Nullable; +import com.facebook.react.bridge.ReadableMap; +import com.google.android.gms.maps.GoogleMapOptions; +import com.google.android.gms.maps.model.CameraPosition; + +/** Class to hold view properties before the map/nav fragment is fully initialized. */ +public class GMNViewProps { + // Flags to inform if data is set (even if null) + boolean initialCameraPositionSet = false; + boolean initialCompassEnabledSet = false; + boolean initialMaxZoomPreferenceSet = false; + boolean initialMinZoomPreferenceSet = false; + boolean initialMapIdSet = false; + boolean initialRotateGesturesEnabledSet = false; + boolean initialScrollGesturesEnabledSet = false; + boolean initialScrollGesturesEnabledDuringRotateOrZoomSet = false; + boolean initialZoomGesturesEnabledSet = false; + boolean initialZoomControlsEnabledSet = false; + boolean initialMapTypeSet = false; + boolean initialTiltGesturesEnabledSet = false; + + // Data + @Nullable String mapId; + @Nullable Boolean navigationUIEnabled; + @Nullable Integer mapType; + @Nullable ReadableMap mapPadding; + @Nullable Boolean tripProgressBarEnabled; + @Nullable Boolean trafficIncidentsCardEnabled; + @Nullable Boolean headerEnabled; + @Nullable Boolean footerEnabled; + @Nullable Boolean speedometerEnabled; + @Nullable Boolean speedLimitIconEnabled; + @Nullable Boolean recenterButtonEnabled; + @Nullable ReadableMap navigationViewStylingOptions; + @Nullable Integer nightMode; + @Nullable Integer followingPerspective; + @Nullable String mapStyle; + @Nullable Boolean mapToolbarEnabled; + @Nullable Boolean indoorEnabled; + @Nullable Boolean trafficEnabled; + @Nullable Boolean compassEnabled; + @Nullable Boolean myLocationButtonEnabled; + @Nullable Boolean myLocationEnabled; + @Nullable Boolean rotateGesturesEnabled; + @Nullable Boolean scrollGesturesEnabled; + @Nullable Boolean scrollGesturesEnabledDuringRotateOrZoom; + @Nullable Boolean tiltGesturesEnabled; + @Nullable Boolean zoomControlsEnabled; + @Nullable Boolean zoomGesturesEnabled; + @Nullable Boolean buildingsEnabled; + + @Nullable Boolean reportIncidentButtonEnabled; + @Nullable Float minZoomPreference; + @Nullable Float maxZoomPreference; + @Nullable CameraPosition initialCameraPosition; + + boolean hasPropsSetForViewInitialization() { + return initialCameraPositionSet + && initialCompassEnabledSet + && initialMaxZoomPreferenceSet + && initialMinZoomPreferenceSet + && initialMapIdSet + && initialRotateGesturesEnabledSet + && initialScrollGesturesEnabledSet + && initialScrollGesturesEnabledDuringRotateOrZoomSet + && initialZoomGesturesEnabledSet + && initialZoomControlsEnabledSet + && initialMapTypeSet + && initialTiltGesturesEnabledSet; + } + + public GoogleMapOptions buildMapOptions() { + GoogleMapOptions options = new GoogleMapOptions(); + + if (mapId != null) { + options.mapId(mapId); + } + if (initialCameraPosition != null) { + options.camera(initialCameraPosition); + } + if (compassEnabled != null) { + options.compassEnabled(compassEnabled); + } + if (maxZoomPreference != null) { + options.maxZoomPreference(maxZoomPreference); + } + if (minZoomPreference != null) { + options.minZoomPreference(minZoomPreference); + } + if (rotateGesturesEnabled != null) { + options.rotateGesturesEnabled(rotateGesturesEnabled); + } + if (scrollGesturesEnabled != null) { + options.scrollGesturesEnabled(scrollGesturesEnabled); + } + if (scrollGesturesEnabledDuringRotateOrZoom != null) { + options.scrollGesturesEnabledDuringRotateOrZoom(scrollGesturesEnabledDuringRotateOrZoom); + } + if (zoomGesturesEnabled != null) { + options.zoomGesturesEnabled(zoomGesturesEnabled); + } + if (zoomControlsEnabled != null) { + options.zoomControlsEnabled(zoomControlsEnabled); + } + if (tiltGesturesEnabled != null) { + options.tiltGesturesEnabled(tiltGesturesEnabled); + } + if (mapType != null) { + options.mapType(mapType); + } + return options; + } +} diff --git a/android/src/main/java/com/google/maps/android/rn/navsdk/IGMNMapViewCallback.java b/android/src/main/java/com/google/maps/android/rn/navsdk/IGMNMapViewCallback.java new file mode 100644 index 00000000..3653875b --- /dev/null +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/IGMNMapViewCallback.java @@ -0,0 +1,34 @@ +/** + * Copyright 2023 Google LLC + * + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + *

http://www.apache.org/licenses/LICENSE-2.0 + * + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.maps.android.rn.navsdk; + +import com.google.android.gms.maps.model.LatLng; + +public interface IGMNMapViewCallback { + void onMapReady(); + + void onMarkerClick(GMNMarker marker); + + void onPolylineClick(GMNPolyline polyline); + + void onPolygonClick(GMNPolygon polygon); + + void onCircleClick(GMNCircle circle); + + void onGroundOverlayClick(GMNGroundOverlay groundOverlay); + + void onMarkerInfoWindowTapped(GMNMarker marker); + + void onMapClick(LatLng latLng); +} diff --git a/android/src/main/java/com/google/android/react/navsdk/IMapViewFragment.java b/android/src/main/java/com/google/maps/android/rn/navsdk/IGMNMapViewFragment.java similarity index 77% rename from android/src/main/java/com/google/android/react/navsdk/IMapViewFragment.java rename to android/src/main/java/com/google/maps/android/rn/navsdk/IGMNMapViewFragment.java index f5cde85f..6a248e50 100644 --- a/android/src/main/java/com/google/android/react/navsdk/IMapViewFragment.java +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/IGMNMapViewFragment.java @@ -11,14 +11,14 @@ * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.react.navsdk; +package com.google.maps.android.rn.navsdk; import android.view.View; import com.google.android.gms.maps.GoogleMap; import com.google.android.libraries.navigation.StylingOptions; -public interface IMapViewFragment { - MapViewController getMapController(); +public interface IGMNMapViewFragment { + GMNMapViewController getMapController(); void setStylingOptions(StylingOptions stylingOptions); @@ -28,8 +28,14 @@ public interface IMapViewFragment { GoogleMap getGoogleMap(); + void setMapReadyListener(Runnable listener); + // Fragment boolean isAdded(); View getView(); + + void onMeasure(int measuredWidth, int measuredHeight); + + void onLayout(int width, int height); } diff --git a/android/src/main/java/com/google/android/react/navsdk/INavViewFragment.java b/android/src/main/java/com/google/maps/android/rn/navsdk/IGMNNavViewFragment.java similarity index 86% rename from android/src/main/java/com/google/android/react/navsdk/INavViewFragment.java rename to android/src/main/java/com/google/maps/android/rn/navsdk/IGMNNavViewFragment.java index 84057f5f..6f926920 100644 --- a/android/src/main/java/com/google/android/react/navsdk/INavViewFragment.java +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/IGMNNavViewFragment.java @@ -11,9 +11,9 @@ * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.react.navsdk; +package com.google.maps.android.rn.navsdk; -public interface INavViewFragment extends IMapViewFragment { +public interface IGMNNavViewFragment extends IGMNMapViewFragment { void setNavigationUiEnabled(boolean enableNavigationUi); void setTripProgressBarEnabled(boolean enabled); @@ -33,4 +33,6 @@ public interface INavViewFragment extends IMapViewFragment { void showRouteOverview(); void setNightModeOption(int jsValue); + + void setReportIncidentButtonEnabled(boolean enabled); } diff --git a/android/src/main/java/com/google/android/react/navsdk/INavigationAutoCallback.java b/android/src/main/java/com/google/maps/android/rn/navsdk/IGMNNavigationAutoCallback.java similarity index 88% rename from android/src/main/java/com/google/android/react/navsdk/INavigationAutoCallback.java rename to android/src/main/java/com/google/maps/android/rn/navsdk/IGMNNavigationAutoCallback.java index 302871ef..f6ef0e79 100644 --- a/android/src/main/java/com/google/android/react/navsdk/INavigationAutoCallback.java +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/IGMNNavigationAutoCallback.java @@ -11,10 +11,10 @@ * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.react.navsdk; +package com.google.maps.android.rn.navsdk; import com.facebook.react.bridge.ReadableMap; -public interface INavigationAutoCallback { +public interface IGMNNavigationAutoCallback { void onCustomNavigationAutoEvent(String type, ReadableMap data); } diff --git a/android/src/main/java/com/google/android/react/navsdk/INavigationCallback.java b/android/src/main/java/com/google/maps/android/rn/navsdk/IGMNNavigationCallback.java similarity index 88% rename from android/src/main/java/com/google/android/react/navsdk/INavigationCallback.java rename to android/src/main/java/com/google/maps/android/rn/navsdk/IGMNNavigationCallback.java index 69c2a158..c4dcb3fd 100644 --- a/android/src/main/java/com/google/android/react/navsdk/INavigationCallback.java +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/IGMNNavigationCallback.java @@ -11,8 +11,8 @@ * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.react.navsdk; +package com.google.maps.android.rn.navsdk; -public interface INavigationCallback { +public interface IGMNNavigationCallback { void logDebugInfo(String info); } diff --git a/android/src/main/java/com/google/maps/android/rn/navsdk/IGMNNavigationViewCallback.java b/android/src/main/java/com/google/maps/android/rn/navsdk/IGMNNavigationViewCallback.java new file mode 100644 index 00000000..159a37a8 --- /dev/null +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/IGMNNavigationViewCallback.java @@ -0,0 +1,20 @@ +/** + * Copyright 2023 Google LLC + * + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + *

http://www.apache.org/licenses/LICENSE-2.0 + * + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.maps.android.rn.navsdk; + +public interface IGMNNavigationViewCallback extends IGMNMapViewCallback { + void onRecenterButtonClick(); + + void onPromptVisibilityChanged(boolean isVisible); +} diff --git a/android/src/main/java/com/google/android/react/navsdk/INavigationViewController.java b/android/src/main/java/com/google/maps/android/rn/navsdk/IGMNNavigationViewController.java similarity index 88% rename from android/src/main/java/com/google/android/react/navsdk/INavigationViewController.java rename to android/src/main/java/com/google/maps/android/rn/navsdk/IGMNNavigationViewController.java index b1546efe..b0996550 100644 --- a/android/src/main/java/com/google/android/react/navsdk/INavigationViewController.java +++ b/android/src/main/java/com/google/maps/android/rn/navsdk/IGMNNavigationViewController.java @@ -11,10 +11,10 @@ * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.react.navsdk; +package com.google.maps.android.rn.navsdk; import com.google.android.libraries.navigation.StylingOptions; -public interface INavigationViewController { +public interface IGMNNavigationViewController { void setStylingOptions(StylingOptions stylingOptions); } diff --git a/android/src/main/res/layout/fragment_nav_view.xml b/android/src/main/res/layout/fragment_nav_view.xml deleted file mode 100644 index 579a7a79..00000000 --- a/android/src/main/res/layout/fragment_nav_view.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app.json b/app.json deleted file mode 100644 index 80fd5e76..00000000 --- a/app.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "react-native-navigation-sdk", - "displayName": "react-native-navigation-sdk" -} diff --git a/babel.config.js b/babel.config.js index d0978277..7bc076d4 100644 --- a/babel.config.js +++ b/babel.config.js @@ -15,5 +15,5 @@ */ module.exports = { - presets: ['module:@react-native/babel-preset'], + presets: ['module:react-native-builder-bob/babel-preset'], }; diff --git a/example/.detoxrc.js b/example/.detoxrc.js index 34cb0d98..eec169af 100644 --- a/example/.detoxrc.js +++ b/example/.detoxrc.js @@ -29,16 +29,16 @@ module.exports = { 'ios.debug': { type: 'ios.app', binaryPath: - 'ios/build/Build/Products/Debug-iphonesimulator/SampleApp.app', + 'ios/build/Build/Products/Debug-iphonesimulator/ReactNativeNavigationSdkExample.app', build: - 'xcodebuild -workspace ios/SampleApp.xcworkspace -scheme SampleApp -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build', + 'xcodebuild -workspace ios/ReactNativeNavigationSdkExample.xcworkspace -scheme ReactNativeNavigationSdkExample -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build', }, 'ios.release': { type: 'ios.app', binaryPath: - 'ios/build/Build/Products/Release-iphonesimulator/SampleApp.app', + 'ios/build/Build/Products/Release-iphonesimulator/ReactNativeNavigationSdkExample.app', build: - 'xcodebuild -workspace ios/SampleApp.xcworkspace -scheme SampleApp -configuration Release -sdk iphonesimulator -derivedDataPath ios/build', + 'xcodebuild -workspace ios/ReactNativeNavigationSdkExample.xcworkspace -scheme ReactNativeNavigationSdkExample -configuration Release -sdk iphonesimulator -derivedDataPath ios/build', }, 'android.debug': { type: 'android.apk', @@ -59,6 +59,7 @@ module.exports = { type: 'ios.simulator', device: { type: 'iPhone 16 Pro', + os: 'iOS 18.4', }, }, attached: { @@ -70,7 +71,7 @@ module.exports = { emulator: { type: 'android.emulator', device: { - avdName: 'Pixel_8_API_35', + avdName: 'Pixel_9_Pro_API_35', }, }, }, diff --git a/example/.watchmanconfig b/example/.watchmanconfig new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/example/.watchmanconfig @@ -0,0 +1 @@ +{} diff --git a/example/Gemfile b/example/Gemfile index 39062042..75913f2e 100644 --- a/example/Gemfile +++ b/example/Gemfile @@ -1,4 +1,4 @@ -# Copyright 2024 Google LLC +# Copyright 2025 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -21,3 +21,4 @@ ruby ">= 2.6.10" gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1' gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0' gem 'xcodeproj', '< 1.26.0' +gem 'concurrent-ruby', '< 1.3.4' diff --git a/example/Gemfile.lock b/example/Gemfile.lock new file mode 100644 index 00000000..8b0fcce8 --- /dev/null +++ b/example/Gemfile.lock @@ -0,0 +1,120 @@ +GEM + remote: https://rubygems.org/ + specs: + CFPropertyList (3.0.7) + base64 + nkf + rexml + activesupport (7.2.2.1) + base64 + benchmark (>= 0.3) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + logger (>= 1.4.2) + minitest (>= 5.1) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + algoliasearch (1.27.5) + httpclient (~> 2.8, >= 2.8.3) + json (>= 1.5.1) + atomos (0.1.3) + base64 (0.2.0) + benchmark (0.4.0) + bigdecimal (3.1.9) + claide (1.1.0) + cocoapods (1.15.2) + addressable (~> 2.8) + claide (>= 1.0.2, < 2.0) + cocoapods-core (= 1.15.2) + cocoapods-deintegrate (>= 1.0.3, < 2.0) + cocoapods-downloader (>= 2.1, < 3.0) + cocoapods-plugins (>= 1.0.0, < 2.0) + cocoapods-search (>= 1.0.0, < 2.0) + cocoapods-trunk (>= 1.6.0, < 2.0) + cocoapods-try (>= 1.1.0, < 2.0) + colored2 (~> 3.1) + escape (~> 0.0.4) + fourflusher (>= 2.3.0, < 3.0) + gh_inspector (~> 1.0) + molinillo (~> 0.8.0) + nap (~> 1.0) + ruby-macho (>= 2.3.0, < 3.0) + xcodeproj (>= 1.23.0, < 2.0) + cocoapods-core (1.15.2) + activesupport (>= 5.0, < 8) + addressable (~> 2.8) + algoliasearch (~> 1.0) + concurrent-ruby (~> 1.1) + fuzzy_match (~> 2.0.4) + nap (~> 1.0) + netrc (~> 0.11) + public_suffix (~> 4.0) + typhoeus (~> 1.0) + cocoapods-deintegrate (1.0.5) + cocoapods-downloader (2.1) + cocoapods-plugins (1.0.0) + nap + cocoapods-search (1.0.1) + cocoapods-trunk (1.6.0) + nap (>= 0.8, < 2.0) + netrc (~> 0.11) + cocoapods-try (1.2.0) + colored2 (3.1.2) + concurrent-ruby (1.3.3) + connection_pool (2.5.0) + drb (2.2.1) + escape (0.0.4) + ethon (0.16.0) + ffi (>= 1.15.0) + ffi (1.17.1) + fourflusher (2.3.1) + fuzzy_match (2.0.4) + gh_inspector (1.1.3) + httpclient (2.9.0) + mutex_m + i18n (1.14.7) + concurrent-ruby (~> 1.0) + json (2.10.2) + logger (1.6.6) + minitest (5.25.5) + molinillo (0.8.0) + mutex_m (0.3.0) + nanaimo (0.3.0) + nap (1.1.0) + netrc (0.11.0) + nkf (0.2.0) + public_suffix (4.0.7) + rexml (3.4.1) + ruby-macho (2.5.1) + securerandom (0.4.1) + typhoeus (1.4.1) + ethon (>= 0.9.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + xcodeproj (1.25.1) + CFPropertyList (>= 2.3.3, < 4.0) + atomos (~> 0.1.3) + claide (>= 1.0.2, < 2.0) + colored2 (~> 3.1) + nanaimo (~> 0.3.0) + rexml (>= 3.3.6, < 4.0) + +PLATFORMS + ruby + +DEPENDENCIES + activesupport (>= 6.1.7.5, != 7.1.0) + cocoapods (>= 1.13, != 1.15.1, != 1.15.0) + concurrent-ruby (< 1.3.4) + xcodeproj (< 1.26.0) + +RUBY VERSION + ruby 3.2.2p53 + +BUNDLED WITH + 2.4.10 diff --git a/example/README.md b/example/README.md index febc53bc..bd34dd78 100644 --- a/example/README.md +++ b/example/README.md @@ -22,7 +22,7 @@ First, make sure you go through the setup from the main [README](../README.md). `RCT_NEW_ARCH_ENABLED=0 pod install` -2. Copy the `Keys.plist.sample` file located in `example/ios/SampleApp/` to a new file named `Keys.plist`. This file is git ignored and won't be accidentally committed. In your Google cloud console, add the Google API key to the project and add this newly created API key to the `Keys.plist` file. +2. Copy the `Keys.plist.sample` file located in `example/ios/ReactNativeNavigationSdkExample/` to a new file named `Keys.plist`. This file is git ignored and won't be accidentally committed. In your Google cloud console, add the Google API key to the project and add this newly created API key to the `Keys.plist` file. ```xml API_KEY diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 7bd7261e..0dd98ddc 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -13,6 +13,7 @@ // limitations under the License. apply plugin: "com.android.application" +apply plugin: "org.jetbrains.kotlin.android" apply plugin: "com.facebook.react" apply plugin: 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' @@ -74,7 +75,7 @@ react { /** * Set this to true to Run Proguard on Release builds to minify the Java bytecode. */ -def enableProguardInReleaseBuilds = true +def enableProguardInReleaseBuilds = false /** @@ -87,23 +88,23 @@ def enableDesugaring = false * The preferred build flavor of JavaScriptCore (JSC) * * For example, to use the international variant, you can use: - * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` + * `def jscFlavor = io.github.react-native-community:jsc-android-intl:2026004.+` * * The international variant includes ICU i18n library and necessary data * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that * give correct results when using with locales other than en-US. Note that * this variant is about 6MiB larger per architecture than default. */ -def jscFlavor = 'org.webkit:android-jsc:+' +def jscFlavor = 'io.github.react-native-community:jsc-android:2026004.+' android { ndkVersion rootProject.ext.ndkVersion buildToolsVersion rootProject.ext.buildToolsVersion compileSdk rootProject.ext.compileSdkVersion - namespace "com.sampleapp" + namespace "com.google.maps.android.rn.navsdkexample" defaultConfig { - applicationId "com.sampleapp" + applicationId "com.google.maps.android.rn.navsdkexample" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1 @@ -154,13 +155,27 @@ dependencies { implementation "androidx.car.app:app:1.4.0" implementation "androidx.car.app:app-projected:1.4.0" - // Include the Google Navigation SDK. - implementation 'com.google.android.libraries.navigation:navigation:6.1.0' + // Navigation SDK library + implementation 'com.google.android.libraries.navigation:navigation:6.2.1' // Desugar Java 8+ APIs coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.3' } +// Run Codegen during development for the example app. +tasks.register('invokeLibraryCodegen', Exec) { + workingDir "$rootDir/../../" + def isWindows = System.getProperty('os.name').toLowerCase().contains('windows') + + if (isWindows) { + commandLine 'cmd', '/c', 'npx bob build --target codegen' + } else { + commandLine 'sh', '-c', 'npx bob build --target codegen' + } +} + +preBuild.dependsOn invokeLibraryCodegen + secrets { // This example application employs the Gradle plugin // com.google.android.libraries.mapsplatform.secrets-gradle-plugin diff --git a/example/android/app/src/androidTest/java/com/sampleapp/DetoxTest.java b/example/android/app/src/androidTest/java/com/google/maps/android/rn/navsdkexample/DetoxTest.java similarity index 96% rename from example/android/app/src/androidTest/java/com/sampleapp/DetoxTest.java rename to example/android/app/src/androidTest/java/com/google/maps/android/rn/navsdkexample/DetoxTest.java index 145b6414..0466b11e 100644 --- a/example/android/app/src/androidTest/java/com/sampleapp/DetoxTest.java +++ b/example/android/app/src/androidTest/java/com/google/maps/android/rn/navsdkexample/DetoxTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.sampleapp; +package com.google.maps.android.rn.navsdkexample; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.LargeTest; @@ -28,7 +28,7 @@ @RunWith(AndroidJUnit4.class) @LargeTest public class DetoxTest { - @Rule // (2) + @Rule public ActivityTestRule mActivityRule = new ActivityTestRule<>(MainActivity.class, false, false); diff --git a/example/android/app/src/debug/AndroidManifest.xml b/example/android/app/src/debug/AndroidManifest.xml index 004568a8..c42fd353 100644 --- a/example/android/app/src/debug/AndroidManifest.xml +++ b/example/android/app/src/debug/AndroidManifest.xml @@ -1,12 +1,12 @@ + - - - - + tools:targetApi="28" + tools:ignore="GoogleAppIndexingWarning"/> diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 55a8cfe5..94914459 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -1,11 +1,11 @@ - SampleApp - \ No newline at end of file + ReactNativeNavigationSdkExample + diff --git a/example/android/app/src/main/res/values/styles.xml b/example/android/app/src/main/res/values/styles.xml index aeba2448..1f62a918 100644 --- a/example/android/app/src/main/res/values/styles.xml +++ b/example/android/app/src/main/res/values/styles.xml @@ -1,11 +1,11 @@