@stream-io/react-native-callingx 0.1.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. package/Callingx.podspec +23 -0
  2. package/LICENSE +219 -0
  3. package/README.md +392 -0
  4. package/android/bin/build/generated/source/buildConfig/debug/io/getstream/rn/callingx/BuildConfig.class +0 -0
  5. package/android/bin/build/generated/source/codegen/java/io/getstream/rn/callingx/NativeCallingxSpec.class +0 -0
  6. package/android/bin/build/generated/source/codegen/jni/CMakeLists.txt +28 -0
  7. package/android/bin/build/generated/source/codegen/jni/CallingxSpec-generated.cpp +167 -0
  8. package/android/bin/build/generated/source/codegen/jni/CallingxSpec.h +31 -0
  9. package/android/bin/build/generated/source/codegen/jni/react/renderer/components/CallingxSpec/CallingxSpecJSI-generated.cpp +196 -0
  10. package/android/bin/build/generated/source/codegen/jni/react/renderer/components/CallingxSpec/CallingxSpecJSI.h +283 -0
  11. package/android/bin/build/generated/source/codegen/jni/react/renderer/components/CallingxSpec/ComponentDescriptors.cpp +22 -0
  12. package/android/bin/build/generated/source/codegen/jni/react/renderer/components/CallingxSpec/ComponentDescriptors.h +24 -0
  13. package/android/bin/build/generated/source/codegen/jni/react/renderer/components/CallingxSpec/EventEmitters.cpp +16 -0
  14. package/android/bin/build/generated/source/codegen/jni/react/renderer/components/CallingxSpec/EventEmitters.h +17 -0
  15. package/android/bin/build/generated/source/codegen/jni/react/renderer/components/CallingxSpec/Props.cpp +19 -0
  16. package/android/bin/build/generated/source/codegen/jni/react/renderer/components/CallingxSpec/Props.h +18 -0
  17. package/android/bin/build/generated/source/codegen/jni/react/renderer/components/CallingxSpec/ShadowNodes.cpp +17 -0
  18. package/android/bin/build/generated/source/codegen/jni/react/renderer/components/CallingxSpec/ShadowNodes.h +23 -0
  19. package/android/bin/build/generated/source/codegen/jni/react/renderer/components/CallingxSpec/States.cpp +16 -0
  20. package/android/bin/build/generated/source/codegen/jni/react/renderer/components/CallingxSpec/States.h +20 -0
  21. package/android/bin/build/generated/source/codegen/schema.json +1 -0
  22. package/android/bin/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +33 -0
  23. package/android/bin/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +18 -0
  24. package/android/bin/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +6 -0
  25. package/android/bin/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +1 -0
  26. package/android/bin/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  27. package/android/bin/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
  28. package/android/bin/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +3 -0
  29. package/android/bin/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/drawable_ic_phone_paused_24.xml.flat +0 -0
  30. package/android/bin/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/drawable_ic_round_call_24.xml.flat +0 -0
  31. package/android/bin/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/drawable_ic_user.xml.flat +0 -0
  32. package/android/bin/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +4 -0
  33. package/android/bin/build/intermediates/incremental/debug/packageDebugResources/merger.xml +2 -0
  34. package/android/bin/build/intermediates/incremental/mergeDebugAssets/merger.xml +2 -0
  35. package/android/bin/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +2 -0
  36. package/android/bin/build/intermediates/incremental/mergeDebugShaders/merger.xml +2 -0
  37. package/android/bin/build/intermediates/java_res/debug/processDebugJavaRes/out/META-INF/stream-io_react-native-callingx_debug.kotlin_module +0 -0
  38. package/android/bin/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +5 -0
  39. package/android/bin/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +60 -0
  40. package/android/bin/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +33 -0
  41. package/android/bin/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +1 -0
  42. package/android/bin/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +1 -0
  43. package/android/bin/build/intermediates/packaged_res/debug/packageDebugResources/drawable/ic_phone_paused_24.xml +11 -0
  44. package/android/bin/build/intermediates/packaged_res/debug/packageDebugResources/drawable/ic_round_call_24.xml +11 -0
  45. package/android/bin/build/intermediates/packaged_res/debug/packageDebugResources/drawable/ic_user.xml +27 -0
  46. package/android/bin/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/META-INF/stream-io_react-native-callingx_debug.kotlin_module +0 -0
  47. package/android/bin/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  48. package/android/bin/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +4 -0
  49. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
  50. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream +0 -0
  51. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len +0 -0
  52. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len +0 -0
  53. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
  54. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i +0 -0
  55. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len +0 -0
  56. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
  57. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +0 -0
  58. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len +0 -0
  59. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len +0 -0
  60. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
  61. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +0 -0
  62. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len +0 -0
  63. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
  64. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +0 -0
  65. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len +0 -0
  66. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len +0 -0
  67. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
  68. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +0 -0
  69. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len +0 -0
  70. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab +0 -0
  71. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream +0 -0
  72. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream.len +0 -0
  73. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.len +0 -0
  74. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.values.at +0 -0
  75. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i +0 -0
  76. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i.len +0 -0
  77. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
  78. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +0 -0
  79. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len +0 -0
  80. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len +0 -0
  81. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
  82. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +0 -0
  83. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len +0 -0
  84. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab +0 -0
  85. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.keystream +0 -0
  86. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.keystream.len +0 -0
  87. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.len +0 -0
  88. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.values.at +0 -0
  89. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab_i +0 -0
  90. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab_i.len +0 -0
  91. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
  92. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +0 -0
  93. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len +0 -0
  94. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len +0 -0
  95. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values +0 -0
  96. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
  97. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.s +1 -0
  98. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +0 -0
  99. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len +0 -0
  100. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
  101. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream +0 -0
  102. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len +0 -0
  103. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len +0 -0
  104. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
  105. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i +0 -0
  106. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len +0 -0
  107. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
  108. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream +0 -0
  109. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len +0 -0
  110. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len +0 -0
  111. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
  112. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i +0 -0
  113. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len +0 -0
  114. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
  115. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream +0 -0
  116. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len +0 -0
  117. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len +0 -0
  118. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
  119. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i +0 -0
  120. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len +0 -0
  121. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +2 -0
  122. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
  123. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream +0 -0
  124. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len +0 -0
  125. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len +0 -0
  126. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
  127. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i +0 -0
  128. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len +0 -0
  129. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
  130. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
  131. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
  132. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
  133. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
  134. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i +0 -0
  135. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len +0 -0
  136. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
  137. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
  138. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
  139. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
  140. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
  141. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
  142. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len +0 -0
  143. package/android/bin/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
  144. package/android/bin/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
  145. package/android/bin/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
  146. package/android/bin/build/outputs/logs/manifest-merger-debug-report.txt +70 -0
  147. package/android/bin/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  148. package/android/bin/build/tmp/kotlin-classes/debug/META-INF/stream-io_react-native-callingx_debug.kotlin_module +0 -0
  149. package/android/bin/build.gradle +81 -0
  150. package/android/bin/gradle.properties +5 -0
  151. package/android/bin/local.properties +8 -0
  152. package/android/bin/src/main/AndroidManifest.xml +30 -0
  153. package/android/bin/src/main/java/io/getstream/rn/callingx/CallService.kt +396 -0
  154. package/android/bin/src/main/java/io/getstream/rn/callingx/CallingxModule.kt +639 -0
  155. package/android/bin/src/main/java/io/getstream/rn/callingx/CallingxPackage.kt +16 -0
  156. package/android/bin/src/main/java/io/getstream/rn/callingx/HeadlessTaskManager.kt +164 -0
  157. package/android/bin/src/main/java/io/getstream/rn/callingx/ResourceUtils.kt +60 -0
  158. package/android/bin/src/main/java/io/getstream/rn/callingx/Utils.kt +23 -0
  159. package/android/bin/src/main/java/io/getstream/rn/callingx/model/Call.kt +57 -0
  160. package/android/bin/src/main/java/io/getstream/rn/callingx/model/CallAction.kt +36 -0
  161. package/android/bin/src/main/java/io/getstream/rn/callingx/notifications/CallNotificationManager.kt +215 -0
  162. package/android/bin/src/main/java/io/getstream/rn/callingx/notifications/NotificationChannelsManager.kt +113 -0
  163. package/android/bin/src/main/java/io/getstream/rn/callingx/notifications/NotificationIntentFactory.kt +105 -0
  164. package/android/bin/src/main/java/io/getstream/rn/callingx/notifications/NotificationReceiverActivity.kt +42 -0
  165. package/android/bin/src/main/java/io/getstream/rn/callingx/notifications/NotificationReceiverService.kt +56 -0
  166. package/android/bin/src/main/java/io/getstream/rn/callingx/notifications/NotificationsConfig.kt +116 -0
  167. package/android/bin/src/main/java/io/getstream/rn/callingx/repo/CallRepository.kt +163 -0
  168. package/android/bin/src/main/java/io/getstream/rn/callingx/repo/LegacyCallRepository.kt +134 -0
  169. package/android/bin/src/main/java/io/getstream/rn/callingx/repo/TelecomCallRepository.kt +438 -0
  170. package/android/bin/src/main/res/drawable/ic_phone_paused_24.xml +11 -0
  171. package/android/bin/src/main/res/drawable/ic_round_call_24.xml +11 -0
  172. package/android/bin/src/main/res/drawable/ic_user.xml +27 -0
  173. package/android/build.gradle +81 -0
  174. package/android/gradle.properties +5 -0
  175. package/android/src/main/AndroidManifest.xml +30 -0
  176. package/android/src/main/java/io/getstream/rn/callingx/CallService.kt +396 -0
  177. package/android/src/main/java/io/getstream/rn/callingx/CallingxModule.kt +639 -0
  178. package/android/src/main/java/io/getstream/rn/callingx/CallingxPackage.kt +16 -0
  179. package/android/src/main/java/io/getstream/rn/callingx/HeadlessTaskManager.kt +164 -0
  180. package/android/src/main/java/io/getstream/rn/callingx/ResourceUtils.kt +60 -0
  181. package/android/src/main/java/io/getstream/rn/callingx/Utils.kt +23 -0
  182. package/android/src/main/java/io/getstream/rn/callingx/model/Call.kt +57 -0
  183. package/android/src/main/java/io/getstream/rn/callingx/model/CallAction.kt +36 -0
  184. package/android/src/main/java/io/getstream/rn/callingx/notifications/CallNotificationManager.kt +215 -0
  185. package/android/src/main/java/io/getstream/rn/callingx/notifications/NotificationChannelsManager.kt +113 -0
  186. package/android/src/main/java/io/getstream/rn/callingx/notifications/NotificationIntentFactory.kt +105 -0
  187. package/android/src/main/java/io/getstream/rn/callingx/notifications/NotificationReceiverActivity.kt +42 -0
  188. package/android/src/main/java/io/getstream/rn/callingx/notifications/NotificationReceiverService.kt +56 -0
  189. package/android/src/main/java/io/getstream/rn/callingx/notifications/NotificationsConfig.kt +116 -0
  190. package/android/src/main/java/io/getstream/rn/callingx/repo/CallRepository.kt +163 -0
  191. package/android/src/main/java/io/getstream/rn/callingx/repo/LegacyCallRepository.kt +134 -0
  192. package/android/src/main/java/io/getstream/rn/callingx/repo/TelecomCallRepository.kt +438 -0
  193. package/android/src/main/res/drawable/ic_phone_paused_24.xml +11 -0
  194. package/android/src/main/res/drawable/ic_round_call_24.xml +11 -0
  195. package/android/src/main/res/drawable/ic_user.xml +27 -0
  196. package/dist/module/CallingxModule.js +191 -0
  197. package/dist/module/CallingxModule.js.map +1 -0
  198. package/dist/module/EventManager.js +40 -0
  199. package/dist/module/EventManager.js.map +1 -0
  200. package/dist/module/index.js +5 -0
  201. package/dist/module/index.js.map +1 -0
  202. package/dist/module/package.json +1 -0
  203. package/dist/module/spec/NativeCallingx.js +8 -0
  204. package/dist/module/spec/NativeCallingx.js.map +1 -0
  205. package/dist/module/types.js +4 -0
  206. package/dist/module/types.js.map +1 -0
  207. package/dist/module/utils/constants.js +48 -0
  208. package/dist/module/utils/constants.js.map +1 -0
  209. package/dist/module/utils/headlessTask.js +37 -0
  210. package/dist/module/utils/headlessTask.js.map +1 -0
  211. package/dist/module/utils/permissions.js +86 -0
  212. package/dist/module/utils/permissions.js.map +1 -0
  213. package/dist/module/utils/types.js +2 -0
  214. package/dist/module/utils/types.js.map +1 -0
  215. package/dist/module/utils/utils.js +6 -0
  216. package/dist/module/utils/utils.js.map +1 -0
  217. package/dist/typescript/package.json +1 -0
  218. package/dist/typescript/src/CallingxModule.d.ts +44 -0
  219. package/dist/typescript/src/CallingxModule.d.ts.map +1 -0
  220. package/dist/typescript/src/EventManager.d.ts +11 -0
  221. package/dist/typescript/src/EventManager.d.ts.map +1 -0
  222. package/dist/typescript/src/index.d.ts +3 -0
  223. package/dist/typescript/src/index.d.ts.map +1 -0
  224. package/dist/typescript/src/spec/NativeCallingx.d.ts +132 -0
  225. package/dist/typescript/src/spec/NativeCallingx.d.ts.map +1 -0
  226. package/dist/typescript/src/types.d.ts +249 -0
  227. package/dist/typescript/src/types.d.ts.map +1 -0
  228. package/dist/typescript/src/utils/constants.d.ts +8 -0
  229. package/dist/typescript/src/utils/constants.d.ts.map +1 -0
  230. package/dist/typescript/src/utils/headlessTask.d.ts +8 -0
  231. package/dist/typescript/src/utils/headlessTask.d.ts.map +1 -0
  232. package/dist/typescript/src/utils/permissions.d.ts +8 -0
  233. package/dist/typescript/src/utils/permissions.d.ts.map +1 -0
  234. package/dist/typescript/src/utils/types.d.ts +4 -0
  235. package/dist/typescript/src/utils/types.d.ts.map +1 -0
  236. package/dist/typescript/src/utils/utils.d.ts +2 -0
  237. package/dist/typescript/src/utils/utils.d.ts.map +1 -0
  238. package/ios/AudioSessionManager.swift +46 -0
  239. package/ios/Callingx.mm +280 -0
  240. package/ios/CallingxImpl.swift +744 -0
  241. package/ios/CallingxPublic.h +79 -0
  242. package/ios/Settings.swift +108 -0
  243. package/ios/UUIDStorage.swift +124 -0
  244. package/ios/VoipNotificationsManager.swift +180 -0
  245. package/package.json +112 -0
  246. package/react-native.config.js +8 -0
  247. package/src/CallingxModule.ts +321 -0
  248. package/src/EventManager.ts +61 -0
  249. package/src/index.ts +2 -0
  250. package/src/spec/NativeCallingx.ts +176 -0
  251. package/src/types.ts +323 -0
  252. package/src/utils/constants.ts +55 -0
  253. package/src/utils/headlessTask.ts +52 -0
  254. package/src/utils/permissions.ts +111 -0
  255. package/src/utils/types.ts +5 -0
  256. package/src/utils/utils.ts +6 -0
@@ -0,0 +1,639 @@
1
+ package io.getstream.rn.callingx
2
+
3
+ import android.content.BroadcastReceiver
4
+ import android.content.ComponentName
5
+ import android.content.Context
6
+ import android.content.Intent
7
+ import android.content.IntentFilter
8
+ import android.content.ServiceConnection
9
+ import android.os.Build
10
+ import android.os.Bundle
11
+ import android.os.IBinder
12
+ import android.telecom.DisconnectCause
13
+ import android.util.Log
14
+ import androidx.core.content.ContextCompat
15
+ import androidx.core.net.toUri
16
+ import com.facebook.react.bridge.Arguments
17
+ import com.facebook.react.bridge.LifecycleEventListener
18
+ import com.facebook.react.bridge.Promise
19
+ import com.facebook.react.bridge.ReactApplicationContext
20
+ import com.facebook.react.bridge.ReadableMap
21
+ import com.facebook.react.bridge.WritableArray
22
+ import com.facebook.react.bridge.WritableMap
23
+ import com.facebook.react.bridge.WritableNativeArray
24
+ import com.facebook.react.module.annotations.ReactModule
25
+ import com.facebook.react.modules.core.DeviceEventManagerModule
26
+ import io.getstream.rn.callingx.model.CallAction
27
+ import io.getstream.rn.callingx.notifications.NotificationChannelsManager
28
+ import io.getstream.rn.callingx.notifications.NotificationsConfig
29
+
30
+ @ReactModule(name = CallingxModule.NAME)
31
+ class CallingxModule(reactContext: ReactApplicationContext) : NativeCallingxSpec(reactContext) {
32
+
33
+ companion object {
34
+ const val TAG = "[Callingx] CallingxModule"
35
+ const val NAME = "Callingx"
36
+
37
+ const val EXTRA_CALL_ID = "call_id"
38
+ const val EXTRA_MUTED = "is_muted"
39
+ const val EXTRA_ON_HOLD = "hold"
40
+ const val EXTRA_DISCONNECT_CAUSE = "disconnect_cause"
41
+ const val EXTRA_AUDIO_ENDPOINT = "audio_endpoint"
42
+ const val EXTRA_SOURCE = "source"
43
+
44
+ const val CALL_REGISTERED_ACTION = "call_registered"
45
+ const val CALL_ANSWERED_ACTION = "call_answered"
46
+ // const val CALL_DISCONNECTED_ACTION = "call_disconnected"
47
+ const val CALL_INACTIVE_ACTION = "call_inactive"
48
+ const val CALL_ACTIVE_ACTION = "call_active"
49
+ const val CALL_MUTED_ACTION = "call_muted"
50
+ const val CALL_ENDPOINT_CHANGED_ACTION = "call_endpoint_changed"
51
+ const val CALL_END_ACTION = "call_end"
52
+ // Background task name
53
+ const val HEADLESS_TASK_NAME = "HandleCallBackgroundState"
54
+ const val SERVICE_READY_ACTION = "service_ready"
55
+ }
56
+
57
+ private enum class BindingState {
58
+ UNBOUND,
59
+ BINDING,
60
+ BOUND
61
+ }
62
+
63
+ private var callService: CallService? = null
64
+ private var bindingState = BindingState.UNBOUND
65
+
66
+ private var delayedEvents = WritableNativeArray()
67
+ private var isModuleInitialized = false
68
+ private var canSendEvents = false
69
+ private var isHeadlessTaskRegistered = false
70
+
71
+ private val notificationChannelsManager = NotificationChannelsManager(reactApplicationContext)
72
+ private val callEventBroadcastReceiver = CallEventBroadcastReceiver()
73
+ private val appStateListener =
74
+ object : LifecycleEventListener {
75
+ override fun onHostResume() {}
76
+
77
+ override fun onHostPause() {}
78
+
79
+ override fun onHostDestroy() {
80
+ // App destroyed - force unbind
81
+ debugLog(TAG, "[module] onHostDestroy: App destroyed")
82
+ unbindServiceSafely()
83
+ }
84
+ }
85
+
86
+ init {
87
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
88
+ reactContext.registerReceiver(
89
+ callEventBroadcastReceiver,
90
+ getReceiverFilter(),
91
+ Context.RECEIVER_NOT_EXPORTED
92
+ )
93
+ } else {
94
+ @Suppress("UnspecifiedRegisterReceiverFlag")
95
+ reactContext.registerReceiver(callEventBroadcastReceiver, getReceiverFilter())
96
+ }
97
+ }
98
+
99
+ override fun getName(): String = NAME
100
+
101
+ override fun initialize() {
102
+ super.initialize()
103
+ reactApplicationContext.addLifecycleEventListener(appStateListener)
104
+
105
+ tryToBindIfNeeded()
106
+
107
+ debugLog(TAG, "[module] initialize: Initializing module")
108
+ }
109
+
110
+ override fun invalidate() {
111
+ super.invalidate()
112
+ debugLog(TAG, "[module] invalidate: Invalidating module")
113
+
114
+ unbindServiceSafely()
115
+
116
+ reactApplicationContext.removeLifecycleEventListener(appStateListener)
117
+ reactApplicationContext.unregisterReceiver(callEventBroadcastReceiver)
118
+ isModuleInitialized = false
119
+ }
120
+
121
+ override fun setupiOS(options: ReadableMap) {
122
+ // leave empty
123
+ }
124
+
125
+ override fun setupAndroid(options: ReadableMap) {
126
+ debugLog(TAG, "[module] setupAndroid: Setting up Android: $options")
127
+ val notificationsConfig =
128
+ NotificationsConfig.saveNotificationsConfig(reactApplicationContext, options)
129
+ notificationChannelsManager.setNotificationsConfig(notificationsConfig)
130
+ notificationChannelsManager.createNotificationChannels()
131
+
132
+ isModuleInitialized = true
133
+ }
134
+
135
+ override fun canPostNotifications(): Boolean {
136
+ return notificationChannelsManager.getNotificationStatus().canPost
137
+ }
138
+
139
+ override fun setShouldRejectCallWhenBusy(shouldReject: Boolean) {
140
+ // leave empty
141
+ }
142
+
143
+ override fun getInitialVoipEvents(): WritableArray {
144
+ // leave empty
145
+ return Arguments.createArray()
146
+ }
147
+
148
+ override fun registerVoipToken() {
149
+ // leave empty
150
+ }
151
+
152
+ override fun getInitialEvents(): WritableArray {
153
+ // NOTE: writabel native array can be consumed only once, think of getting rid from clear
154
+ // event and clear eat immidiate after getting initial events
155
+ val events = delayedEvents
156
+ debugLog(TAG, "[module] getInitialEvents: Getting initial events: $events")
157
+ delayedEvents = WritableNativeArray()
158
+ canSendEvents = true
159
+ return events
160
+ }
161
+
162
+ override fun setCurrentCallActive(callId: String, promise: Promise) {
163
+ debugLog(TAG, "[module] activateCall: Activating call: $callId")
164
+ executeServiceAction(callId, CallAction.Activate, promise)
165
+ }
166
+
167
+ override fun displayIncomingCall(
168
+ callId: String,
169
+ phoneNumber: String,
170
+ callerName: String,
171
+ hasVideo: Boolean,
172
+ displayOptions: ReadableMap?,
173
+ promise: Promise
174
+ ) {
175
+ debugLog(
176
+ TAG,
177
+ "[module] displayIncomingCall: Displaying incoming call: $callId, $phoneNumber, $callerName, $hasVideo"
178
+ )
179
+ if (!notificationChannelsManager.getNotificationStatus().canPost) {
180
+ promise.reject("ERROR", "Notifications are not granted")
181
+ return
182
+ }
183
+
184
+ startCallService(
185
+ CallService.ACTION_INCOMING_CALL,
186
+ callId,
187
+ callerName,
188
+ phoneNumber,
189
+ hasVideo,
190
+ displayOptions
191
+ )
192
+
193
+ promise.resolve(true)
194
+ }
195
+
196
+ override fun answerIncomingCall(callId: String, promise: Promise) {
197
+ debugLog(TAG, "[module] answerIncomingCall: Answering call: $callId")
198
+ // TODO: get the call type from the call attributes
199
+ val isAudioCall = true // TODO: get the call type from the call attributes
200
+ // registeredCall.callAttributes.callType ==
201
+ // CallAttributesCompat.CALL_TYPE_AUDIO_CALL
202
+ // currentCall?.processAction(TelecomCallAction.Answer(isAudioCall))
203
+ executeServiceAction(callId, CallAction.Answer(isAudioCall), promise)
204
+ }
205
+
206
+ override fun startCall(
207
+ callId: String,
208
+ phoneNumber: String,
209
+ callerName: String,
210
+ hasVideo: Boolean,
211
+ displayOptions: ReadableMap?,
212
+ promise: Promise
213
+ ) {
214
+ debugLog(
215
+ TAG,
216
+ "[module] startCall: Starting outgoing call: $callId, $phoneNumber, $callerName, $hasVideo, $displayOptions"
217
+ )
218
+ if (!notificationChannelsManager.getNotificationStatus().canPost) {
219
+ promise.reject("ERROR", "Notifications are not granted")
220
+ return
221
+ }
222
+
223
+ startCallService(
224
+ CallService.ACTION_OUTGOING_CALL,
225
+ callId,
226
+ callerName,
227
+ phoneNumber,
228
+ hasVideo,
229
+ displayOptions
230
+ )
231
+
232
+ promise.resolve(true)
233
+ }
234
+
235
+ override fun updateDisplay(
236
+ callId: String,
237
+ phoneNumber: String,
238
+ callerName: String,
239
+ displayOptions: ReadableMap?,
240
+ promise: Promise
241
+ ) {
242
+ debugLog(TAG, "[module] updateDisplay: Updating display: $callId, $phoneNumber, $callerName")
243
+ if (!notificationChannelsManager.getNotificationStatus().canPost) {
244
+ promise.reject("ERROR", "Notifications are not granted")
245
+ return
246
+ }
247
+
248
+ // for now only display options will be updated, rest of the parameters will be ignored
249
+ startCallService(
250
+ CallService.ACTION_UPDATE_CALL,
251
+ callId,
252
+ callerName,
253
+ phoneNumber,
254
+ true,
255
+ displayOptions,
256
+ )
257
+ promise.resolve(true)
258
+ }
259
+
260
+ override fun endCallWithReason(callId: String, reason: Double, promise: Promise) {
261
+ debugLog(TAG, "[module] endCallWithReason: Ending call: $callId, $reason")
262
+ val action = CallAction.Disconnect(DisconnectCause(reason.toInt()))
263
+ executeServiceAction(callId, action, promise)
264
+ }
265
+
266
+ override fun endCall(callId: String, promise: Promise) {
267
+ debugLog(TAG, "[module] endCall: Ending call: $callId")
268
+ val action = CallAction.Disconnect(DisconnectCause(DisconnectCause.LOCAL))
269
+ executeServiceAction(callId, action, promise)
270
+ }
271
+
272
+ override fun isCallRegistered(callId: String): Boolean {
273
+ val isCallRegistered = callService?.isCallRegistered(callId) ?: false
274
+ debugLog(TAG, "[module] isCallRegistered: Is call registered: $isCallRegistered")
275
+ return isCallRegistered
276
+ }
277
+
278
+ override fun hasRegisteredCall(): Boolean {
279
+ val hasRegisteredCall = callService?.hasRegisteredCall() ?: false
280
+ debugLog(TAG, "[module] hasRegisteredCall: Has registered call: $hasRegisteredCall")
281
+ return hasRegisteredCall
282
+ }
283
+
284
+ override fun setMutedCall(callId: String, isMuted: Boolean, promise: Promise) {
285
+ debugLog(TAG, "[module] setMutedCall: Setting muted call: $callId, $isMuted")
286
+ val action = CallAction.ToggleMute(isMuted)
287
+ executeServiceAction(callId, action, promise)
288
+ }
289
+
290
+ override fun setOnHoldCall(callId: String, isOnHold: Boolean, promise: Promise) {
291
+ debugLog(TAG, "[module] setOnHoldCall: Setting on hold call: $callId, $isOnHold")
292
+ val action = if (isOnHold) CallAction.Hold else CallAction.Activate
293
+ executeServiceAction(callId, action, promise)
294
+ }
295
+
296
+ override fun startBackgroundTask(taskName: String, timeout: Double, promise: Promise) {
297
+ Intent(reactApplicationContext, CallService::class.java)
298
+ .apply {
299
+ this.action = CallService.ACTION_START_BACKGROUND_TASK
300
+ putExtra(CallService.EXTRA_TASK_NAME, taskName)
301
+ putExtra(CallService.EXTRA_TASK_DATA, Bundle())
302
+ putExtra(CallService.EXTRA_TASK_TIMEOUT, timeout.toLong())
303
+ }
304
+ .also { ContextCompat.startForegroundService(reactApplicationContext, it) }
305
+
306
+ promise.resolve(true)
307
+ }
308
+
309
+ override fun stopBackgroundTask(taskName: String, promise: Promise) {
310
+ Intent(reactApplicationContext, CallService::class.java)
311
+ .apply {
312
+ this.action = CallService.ACTION_STOP_BACKGROUND_TASK
313
+ putExtra(CallService.EXTRA_TASK_NAME, taskName)
314
+ }
315
+ .also { ContextCompat.startForegroundService(reactApplicationContext, it) }
316
+
317
+ isHeadlessTaskRegistered = false
318
+ promise.resolve(true)
319
+ }
320
+
321
+ override fun registerBackgroundTaskAvailable() {
322
+ debugLog(TAG, "[module] registerBackgroundTaskAvailable: Headless task registered")
323
+ isHeadlessTaskRegistered = true
324
+ }
325
+
326
+ override fun isServiceStarted(promise: Promise) {
327
+ val isStarted =
328
+ bindingState == BindingState.BOUND ||
329
+ bindingState == BindingState.BINDING ||
330
+ callService?.hasRegisteredCall() == true
331
+ debugLog(TAG, "[module] isServiceStarted: Service started: $isStarted")
332
+ promise.resolve(isStarted)
333
+ }
334
+
335
+ override fun log(message: String, level: String) {
336
+ when (level) {
337
+ "debug" -> debugLog(TAG, "[module] log: $message")
338
+ "info" -> Log.i(TAG, "[module] log: $message")
339
+ "warn" -> Log.w(TAG, "[module] log: $message")
340
+ "error" -> Log.e(TAG, "[module] log: $message")
341
+ }
342
+ }
343
+
344
+ private fun startCallService(
345
+ action: String,
346
+ callId: String,
347
+ callerName: String,
348
+ phoneNumber: String,
349
+ hasVideo: Boolean,
350
+ displayOptions: ReadableMap?
351
+ ) {
352
+ Intent(reactApplicationContext, CallService::class.java)
353
+ .apply {
354
+ this.action = action
355
+ putExtra(CallService.EXTRA_CALL_ID, callId)
356
+ putExtra(CallService.EXTRA_NAME, callerName)
357
+ putExtra(CallService.EXTRA_URI, phoneNumber.toUri())
358
+ putExtra(CallService.EXTRA_IS_VIDEO, hasVideo)
359
+ putExtra(CallService.EXTRA_DISPLAY_OPTIONS, Arguments.toBundle(displayOptions))
360
+ }
361
+ .also { ContextCompat.startForegroundService(reactApplicationContext, it) }
362
+ }
363
+
364
+ private fun startBackgroundTaskAutomatically(taskName: String, timeout: Long) {
365
+ if (!isHeadlessTaskRegistered) {
366
+ debugLog(
367
+ TAG,
368
+ "[module] startBackgroundTaskAutomatically: Headless task registered, starting automatically"
369
+ )
370
+ return
371
+ }
372
+
373
+ Intent(reactApplicationContext, CallService::class.java)
374
+ .apply {
375
+ this.action = CallService.ACTION_START_BACKGROUND_TASK
376
+ putExtra(CallService.EXTRA_TASK_NAME, taskName)
377
+ putExtra(CallService.EXTRA_TASK_DATA, Bundle())
378
+ putExtra(CallService.EXTRA_TASK_TIMEOUT, timeout.toLong())
379
+ }
380
+ .also { ContextCompat.startForegroundService(reactApplicationContext, it) }
381
+ }
382
+
383
+ private fun executeServiceAction(callId: String, action: CallAction, promise: Promise) {
384
+ debugLog(TAG, "[module] executeServiceAction: Executing service action: $action")
385
+ when (bindingState) {
386
+ BindingState.BOUND -> {
387
+ if (callService != null) {
388
+ callService?.processAction(callId, action)
389
+ promise.resolve(true)
390
+ } else {
391
+ promise.reject("ERROR", "Service reference lost")
392
+ }
393
+ }
394
+ BindingState.BINDING -> {
395
+ debugLog(TAG, "executeServiceAction: Service binding, queueing action")
396
+ promise.reject(
397
+ "SERVICE_BINDING",
398
+ "Service is connecting, please try again in a moment"
399
+ )
400
+ }
401
+ BindingState.UNBOUND -> {
402
+ promise.reject(
403
+ "SERVICE_NOT_CONNECTED",
404
+ "Service not connected. Call may not be active."
405
+ )
406
+ }
407
+ }
408
+ }
409
+
410
+ private fun sendJSEvent(eventName: String, params: WritableMap? = null) {
411
+ if (isModuleInitialized && reactApplicationContext.hasActiveReactInstance() && canSendEvents
412
+ ) {
413
+ val paramsMap =
414
+ Arguments.createMap().apply {
415
+ params?.let {
416
+ it.toHashMap().forEach { key, value ->
417
+ if (value is Boolean) {
418
+ putBoolean(key, value)
419
+ } else {
420
+ putString(key, value.toString())
421
+ }
422
+ }
423
+ }
424
+ }
425
+ reactApplicationContext
426
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
427
+ .emit(eventName, params)
428
+
429
+ val value =
430
+ Arguments.createMap().apply {
431
+ putString("eventName", eventName)
432
+ putMap("params", paramsMap)
433
+ }
434
+ emitOnNewEvent(value)
435
+ } else {
436
+ debugLog(TAG, "[module] sendJSEvent: Queueing event: $eventName, $params")
437
+ Arguments.createMap()
438
+ .apply {
439
+ putString("eventName", eventName)
440
+ putMap("params", params)
441
+ }
442
+ .also { delayedEvents.pushMap(it) }
443
+ }
444
+ }
445
+
446
+ private fun getReceiverFilter(): IntentFilter =
447
+ IntentFilter().apply {
448
+ addAction(CALL_REGISTERED_ACTION)
449
+ addAction(CALL_ANSWERED_ACTION)
450
+ addAction(CALL_ACTIVE_ACTION)
451
+ addAction(CALL_INACTIVE_ACTION)
452
+ addAction(CALL_MUTED_ACTION)
453
+ addAction(CALL_ENDPOINT_CHANGED_ACTION)
454
+ addAction(CALL_END_ACTION)
455
+ addAction(SERVICE_READY_ACTION)
456
+ }
457
+
458
+ private fun bindToServiceIfNeeded() {
459
+ when (bindingState) {
460
+ BindingState.BOUND -> {
461
+ debugLog(TAG, "[module] bindToServiceIfNeeded: Already bound")
462
+ return
463
+ }
464
+ BindingState.BINDING -> {
465
+ debugLog(TAG, "[module] bindToServiceIfNeeded: Already binding")
466
+ return
467
+ }
468
+ BindingState.UNBOUND -> {
469
+ debugLog(TAG, "[module] bindToServiceIfNeeded: Attempting to bind")
470
+ val intent = Intent(reactApplicationContext, CallService::class.java)
471
+ try {
472
+ val success =
473
+ reactApplicationContext.bindService(
474
+ intent,
475
+ serviceConnection,
476
+ Context.BIND_AUTO_CREATE or Context.BIND_IMPORTANT
477
+ )
478
+ if (success) {
479
+ bindingState = BindingState.BINDING
480
+ debugLog(TAG, "[module] bindToServiceIfNeeded: Bind request successful")
481
+ } else {
482
+ Log.e(TAG, "[module] bindToServiceIfNeeded: Bind request failed")
483
+ bindingState = BindingState.UNBOUND
484
+ }
485
+ } catch (e: Exception) {
486
+ Log.e(TAG, "[module] bindToServiceIfNeeded: Exception during bind", e)
487
+ bindingState = BindingState.UNBOUND
488
+ }
489
+ }
490
+ }
491
+ }
492
+
493
+ private fun unbindServiceSafely() {
494
+ debugLog(TAG, "[module] unbindServiceSafely: Unbinding service")
495
+ if (bindingState == BindingState.BOUND || bindingState == BindingState.BINDING) {
496
+ try {
497
+ reactApplicationContext.unbindService(serviceConnection)
498
+ debugLog(TAG, "[module] unbindServiceSafely: Successfully unbound")
499
+ } catch (e: IllegalArgumentException) {
500
+ Log.w(
501
+ TAG,
502
+ "[module] unbindServiceSafely: Service not registered or already unbound"
503
+ )
504
+ } catch (e: Exception) {
505
+ Log.e(TAG, "[module] unbindServiceSafely: Error unbinding service", e)
506
+ } finally {
507
+ bindingState = BindingState.UNBOUND
508
+ callService = null
509
+ }
510
+ }
511
+ }
512
+
513
+ private fun tryToBindIfNeeded() {
514
+ val intent = Intent(reactApplicationContext, CallService::class.java)
515
+ try {
516
+ val success =
517
+ reactApplicationContext.bindService(
518
+ intent,
519
+ serviceConnection,
520
+ 0 // No flags - only bind if service exists
521
+ )
522
+ if (success) {
523
+ bindingState = BindingState.BINDING
524
+ debugLog(TAG, "[module] checkForExistingService: Service exists, binding")
525
+ } else {
526
+ debugLog(TAG, "[module] checkForExistingService: No existing service")
527
+ }
528
+ } catch (e: Exception) {
529
+ Log.e(TAG, "[module] checkForExistingService: Error checking for service", e)
530
+ }
531
+ }
532
+
533
+ private inner class CallEventBroadcastReceiver : BroadcastReceiver() {
534
+ override fun onReceive(context: Context, intent: Intent) {
535
+ val action = intent.action
536
+ val callId = intent.getStringExtra(EXTRA_CALL_ID)
537
+
538
+ if (action == null) {
539
+ return
540
+ }
541
+
542
+ debugLog(
543
+ TAG,
544
+ "[module] onReceive: Received intent: $action callId: $callId callService: ${callService != null}"
545
+ )
546
+
547
+ if (action == SERVICE_READY_ACTION) {
548
+ debugLog(TAG, "[module] onReceive: Service is ready, initiating binding, isHeadlessTaskRegistered: $isHeadlessTaskRegistered")
549
+ bindToServiceIfNeeded()
550
+ startBackgroundTaskAutomatically(HEADLESS_TASK_NAME, 0L)
551
+ return
552
+ }
553
+
554
+ val params = Arguments.createMap()
555
+ if (callId != null) {
556
+ params.putString("callId", callId)
557
+ }
558
+
559
+ when (action) {
560
+ CALL_REGISTERED_ACTION -> {
561
+ sendJSEvent("didReceiveStartCallAction", params)
562
+ }
563
+ CALL_ANSWERED_ACTION -> {
564
+ if (intent.hasExtra(EXTRA_SOURCE)) {
565
+ params.putString("source", intent.getStringExtra(EXTRA_SOURCE))
566
+ }
567
+ sendJSEvent("answerCall", params)
568
+ }
569
+ CALL_END_ACTION -> {
570
+ val source = intent.getStringExtra(EXTRA_SOURCE)
571
+ if (source != null) {
572
+ params.putString("source", source)
573
+ }
574
+ if (source == "app") {
575
+ // means the call was disconnected, we're ready to unbind the service
576
+ unbindServiceSafely()
577
+ }
578
+ params.putString("cause", intent.getStringExtra(EXTRA_DISCONNECT_CAUSE))
579
+ sendJSEvent("endCall", params)
580
+ }
581
+ CALL_INACTIVE_ACTION -> {
582
+ params.putBoolean("hold", true)
583
+ sendJSEvent("didToggleHoldCallAction", params)
584
+ }
585
+ CALL_ACTIVE_ACTION -> {
586
+ params.putBoolean("hold", false)
587
+ sendJSEvent("didToggleHoldCallAction", params)
588
+ }
589
+ CALL_MUTED_ACTION -> {
590
+ if (intent.hasExtra(EXTRA_MUTED)) {
591
+ params.putBoolean("muted", intent.getBooleanExtra(EXTRA_MUTED, false))
592
+ }
593
+ sendJSEvent("didPerformSetMutedCallAction", params)
594
+ }
595
+ CALL_ENDPOINT_CHANGED_ACTION -> {
596
+ if (intent.hasExtra(EXTRA_AUDIO_ENDPOINT)) {
597
+ params.putString("output", intent.getStringExtra(EXTRA_AUDIO_ENDPOINT))
598
+ }
599
+ sendJSEvent("didChangeAudioRoute", params)
600
+ }
601
+ }
602
+ }
603
+ }
604
+
605
+ private val serviceConnection =
606
+ object : ServiceConnection {
607
+ override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
608
+ debugLog(TAG, "[module] onServiceConnected: Service connected")
609
+ val binder = service as? CallService.CallServiceBinder
610
+ callService = binder?.getService()
611
+ bindingState = BindingState.BOUND
612
+ }
613
+
614
+ override fun onServiceDisconnected(name: ComponentName?) {
615
+ debugLog(TAG, "onServiceDisconnected: Service disconnected unexpectedly")
616
+ callService = null
617
+ bindingState = BindingState.UNBOUND
618
+ }
619
+
620
+ override fun onBindingDied(name: ComponentName?) {
621
+ Log.e(TAG, "[module] onBindingDied: Service binding died")
622
+ callService = null
623
+ bindingState = BindingState.UNBOUND
624
+
625
+ // Must unbind to clean up the dead binding
626
+ try {
627
+ reactApplicationContext.unbindService(this)
628
+ } catch (e: Exception) {
629
+ Log.w(TAG, "[module] onBindingDied: Error unbinding dead connection", e)
630
+ }
631
+ }
632
+
633
+ override fun onNullBinding(name: ComponentName?) {
634
+ Log.e(TAG, "[module] onNullBinding: Service returned null binding")
635
+ bindingState = BindingState.UNBOUND
636
+ callService = null
637
+ }
638
+ }
639
+ }
@@ -0,0 +1,16 @@
1
+ package io.getstream.rn.callingx
2
+
3
+ import com.facebook.react.BaseReactPackage
4
+ import com.facebook.react.bridge.NativeModule
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.module.model.ReactModuleInfo
7
+ import com.facebook.react.module.model.ReactModuleInfoProvider
8
+
9
+ class CallingPackage : BaseReactPackage() {
10
+ override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? =
11
+ if (name == CallingxModule.NAME) CallingxModule(reactContext) else null
12
+
13
+ override fun getReactModuleInfoProvider(): ReactModuleInfoProvider = ReactModuleInfoProvider {
14
+ mapOf(CallingxModule.NAME to ReactModuleInfo(CallingxModule.NAME, CallingxModule.NAME, false, false, false, true))
15
+ }
16
+ }