react-native-audio-api 0.11.0-nightly-b30bac9-20260114 → 0.11.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 (173) hide show
  1. package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.cpp +3 -10
  2. package/android/src/main/cpp/audioapi/android/core/AudioPlayer.cpp +0 -4
  3. package/android/src/main/java/com/swmansion/audioapi/AudioAPIModule.kt +4 -83
  4. package/android/src/main/java/com/swmansion/audioapi/system/CentralizedForegroundService.kt +14 -29
  5. package/android/src/main/java/com/swmansion/audioapi/system/ForegroundServiceManager.kt +10 -9
  6. package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionManager.kt +10 -51
  7. package/android/src/main/java/com/swmansion/audioapi/system/notification/BaseNotification.kt +6 -14
  8. package/android/src/main/java/com/swmansion/audioapi/system/notification/NotificationRegistry.kt +79 -60
  9. package/android/src/main/java/com/swmansion/audioapi/system/notification/PlaybackNotification.kt +249 -411
  10. package/android/src/main/java/com/swmansion/audioapi/system/notification/PlaybackNotificationReceiver.kt +8 -3
  11. package/android/src/main/java/com/swmansion/audioapi/system/notification/RecordingNotification.kt +240 -222
  12. package/android/src/main/java/com/swmansion/audioapi/system/notification/RecordingNotificationReceiver.kt +11 -22
  13. package/android/src/main/java/com/swmansion/audioapi/system/notification/state/RecordingNotificationState.kt +24 -0
  14. package/android/src/main/res/layout/btn_round_ripple.xml +9 -0
  15. package/android/src/main/res/layout/notification_collapsed.xml +45 -0
  16. package/android/src/main/res/layout/notification_expanded.xml +44 -0
  17. package/android/src/oldarch/NativeAudioAPIModuleSpec.java +1 -13
  18. package/common/cpp/audioapi/core/utils/AudioFileWriter.cpp +1 -1
  19. package/ios/audioapi/ios/AudioAPIModule.mm +5 -48
  20. package/ios/audioapi/ios/system/notification/BaseNotification.h +0 -7
  21. package/ios/audioapi/ios/system/notification/NotificationRegistry.h +5 -25
  22. package/ios/audioapi/ios/system/notification/NotificationRegistry.mm +19 -64
  23. package/ios/audioapi/ios/system/notification/PlaybackNotification.mm +4 -15
  24. package/lib/commonjs/AudioAPIModule/AudioAPIModule.js +2 -1
  25. package/lib/commonjs/AudioAPIModule/AudioAPIModule.js.map +1 -1
  26. package/lib/commonjs/api.js +1 -29
  27. package/lib/commonjs/api.js.map +1 -1
  28. package/lib/commonjs/core/AudioDecoder.js +42 -16
  29. package/lib/commonjs/core/AudioDecoder.js.map +1 -1
  30. package/lib/commonjs/core/AudioRecorder.js +2 -1
  31. package/lib/commonjs/core/AudioRecorder.js.map +1 -1
  32. package/lib/commonjs/core/AudioStretcher.js +2 -1
  33. package/lib/commonjs/core/AudioStretcher.js.map +1 -1
  34. package/lib/commonjs/core/BaseAudioContext.js +2 -5
  35. package/lib/commonjs/core/BaseAudioContext.js.map +1 -1
  36. package/lib/commonjs/errors/AudioApiError.js +14 -0
  37. package/lib/commonjs/errors/AudioApiError.js.map +1 -0
  38. package/lib/commonjs/errors/index.js +7 -0
  39. package/lib/commonjs/errors/index.js.map +1 -1
  40. package/lib/commonjs/specs/NativeAudioAPIModule.js.map +1 -1
  41. package/lib/commonjs/specs/NativeAudioAPIModule.web.js +0 -9
  42. package/lib/commonjs/specs/NativeAudioAPIModule.web.js.map +1 -1
  43. package/lib/commonjs/system/notification/PlaybackNotificationManager.js +40 -85
  44. package/lib/commonjs/system/notification/PlaybackNotificationManager.js.map +1 -1
  45. package/lib/commonjs/system/notification/RecordingNotificationManager.ios.js +51 -0
  46. package/lib/commonjs/system/notification/RecordingNotificationManager.ios.js.map +1 -0
  47. package/lib/commonjs/system/notification/RecordingNotificationManager.js +30 -144
  48. package/lib/commonjs/system/notification/RecordingNotificationManager.js.map +1 -1
  49. package/lib/commonjs/system/notification/index.js +1 -9
  50. package/lib/commonjs/system/notification/index.js.map +1 -1
  51. package/lib/commonjs/utils/index.js +3 -2
  52. package/lib/commonjs/utils/index.js.map +1 -1
  53. package/lib/commonjs/utils/paths.js +18 -0
  54. package/lib/commonjs/utils/paths.js.map +1 -0
  55. package/lib/commonjs/web-core/AudioContext.js +20 -11
  56. package/lib/commonjs/web-core/AudioContext.js.map +1 -1
  57. package/lib/commonjs/web-system/notification/PlaybackNotificationManager.js +0 -1
  58. package/lib/commonjs/web-system/notification/PlaybackNotificationManager.js.map +1 -1
  59. package/lib/commonjs/web-system/notification/RecordingNotificationManager.js +1 -6
  60. package/lib/commonjs/web-system/notification/RecordingNotificationManager.js.map +1 -1
  61. package/lib/module/AudioAPIModule/AudioAPIModule.js +2 -1
  62. package/lib/module/AudioAPIModule/AudioAPIModule.js.map +1 -1
  63. package/lib/module/api.js +3 -2
  64. package/lib/module/api.js.map +1 -1
  65. package/lib/module/core/AudioDecoder.js +42 -16
  66. package/lib/module/core/AudioDecoder.js.map +1 -1
  67. package/lib/module/core/AudioRecorder.js +3 -1
  68. package/lib/module/core/AudioRecorder.js.map +1 -1
  69. package/lib/module/core/AudioStretcher.js +2 -1
  70. package/lib/module/core/AudioStretcher.js.map +1 -1
  71. package/lib/module/core/BaseAudioContext.js +2 -5
  72. package/lib/module/core/BaseAudioContext.js.map +1 -1
  73. package/lib/module/errors/AudioApiError.js +10 -0
  74. package/lib/module/errors/AudioApiError.js.map +1 -0
  75. package/lib/module/errors/index.js +1 -0
  76. package/lib/module/errors/index.js.map +1 -1
  77. package/lib/module/specs/NativeAudioAPIModule.js.map +1 -1
  78. package/lib/module/specs/NativeAudioAPIModule.web.js +0 -9
  79. package/lib/module/specs/NativeAudioAPIModule.web.js.map +1 -1
  80. package/lib/module/system/notification/PlaybackNotificationManager.js +40 -85
  81. package/lib/module/system/notification/PlaybackNotificationManager.js.map +1 -1
  82. package/lib/module/system/notification/RecordingNotificationManager.ios.js +47 -0
  83. package/lib/module/system/notification/RecordingNotificationManager.ios.js.map +1 -0
  84. package/lib/module/system/notification/RecordingNotificationManager.js +30 -144
  85. package/lib/module/system/notification/RecordingNotificationManager.js.map +1 -1
  86. package/lib/module/system/notification/index.js +1 -2
  87. package/lib/module/system/notification/index.js.map +1 -1
  88. package/lib/module/utils/index.js +3 -2
  89. package/lib/module/utils/index.js.map +1 -1
  90. package/lib/module/utils/paths.js +12 -0
  91. package/lib/module/utils/paths.js.map +1 -0
  92. package/lib/module/web-core/AudioContext.js +20 -11
  93. package/lib/module/web-core/AudioContext.js.map +1 -1
  94. package/lib/module/web-system/notification/PlaybackNotificationManager.js +0 -1
  95. package/lib/module/web-system/notification/PlaybackNotificationManager.js.map +1 -1
  96. package/lib/module/web-system/notification/RecordingNotificationManager.js +1 -6
  97. package/lib/module/web-system/notification/RecordingNotificationManager.js.map +1 -1
  98. package/lib/typescript/AudioAPIModule/AudioAPIModule.d.ts.map +1 -1
  99. package/lib/typescript/api.d.ts +3 -2
  100. package/lib/typescript/api.d.ts.map +1 -1
  101. package/lib/typescript/core/AudioDecoder.d.ts +2 -1
  102. package/lib/typescript/core/AudioDecoder.d.ts.map +1 -1
  103. package/lib/typescript/core/AudioRecorder.d.ts.map +1 -1
  104. package/lib/typescript/core/AudioStretcher.d.ts.map +1 -1
  105. package/lib/typescript/core/BaseAudioContext.d.ts +2 -2
  106. package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
  107. package/lib/typescript/errors/AudioApiError.d.ts +5 -0
  108. package/lib/typescript/errors/AudioApiError.d.ts.map +1 -0
  109. package/lib/typescript/errors/index.d.ts +1 -0
  110. package/lib/typescript/errors/index.d.ts.map +1 -1
  111. package/lib/typescript/interfaces.d.ts +1 -1
  112. package/lib/typescript/interfaces.d.ts.map +1 -1
  113. package/lib/typescript/specs/NativeAudioAPIModule.d.ts +2 -5
  114. package/lib/typescript/specs/NativeAudioAPIModule.d.ts.map +1 -1
  115. package/lib/typescript/specs/NativeAudioAPIModule.web.d.ts +1 -4
  116. package/lib/typescript/specs/NativeAudioAPIModule.web.d.ts.map +1 -1
  117. package/lib/typescript/system/notification/PlaybackNotificationManager.d.ts +32 -9
  118. package/lib/typescript/system/notification/PlaybackNotificationManager.d.ts.map +1 -1
  119. package/lib/typescript/system/notification/RecordingNotificationManager.d.ts +26 -13
  120. package/lib/typescript/system/notification/RecordingNotificationManager.d.ts.map +1 -1
  121. package/lib/typescript/system/notification/RecordingNotificationManager.ios.d.ts +36 -0
  122. package/lib/typescript/system/notification/RecordingNotificationManager.ios.d.ts.map +1 -0
  123. package/lib/typescript/system/notification/index.d.ts +0 -1
  124. package/lib/typescript/system/notification/index.d.ts.map +1 -1
  125. package/lib/typescript/system/notification/types.d.ts +12 -22
  126. package/lib/typescript/system/notification/types.d.ts.map +1 -1
  127. package/lib/typescript/types.d.ts +1 -0
  128. package/lib/typescript/types.d.ts.map +1 -1
  129. package/lib/typescript/utils/index.d.ts.map +1 -1
  130. package/lib/typescript/utils/paths.d.ts +4 -0
  131. package/lib/typescript/utils/paths.d.ts.map +1 -0
  132. package/lib/typescript/web-core/AudioContext.d.ts +8 -9
  133. package/lib/typescript/web-core/AudioContext.d.ts.map +1 -1
  134. package/lib/typescript/web-core/BaseAudioContext.d.ts +6 -7
  135. package/lib/typescript/web-core/BaseAudioContext.d.ts.map +1 -1
  136. package/lib/typescript/web-system/notification/PlaybackNotificationManager.d.ts +1 -2
  137. package/lib/typescript/web-system/notification/PlaybackNotificationManager.d.ts.map +1 -1
  138. package/lib/typescript/web-system/notification/RecordingNotificationManager.d.ts +2 -7
  139. package/lib/typescript/web-system/notification/RecordingNotificationManager.d.ts.map +1 -1
  140. package/package.json +1 -1
  141. package/src/AudioAPIModule/AudioAPIModule.ts +2 -1
  142. package/src/api.ts +2 -8
  143. package/src/core/AudioDecoder.ts +91 -21
  144. package/src/core/AudioRecorder.ts +2 -1
  145. package/src/core/AudioStretcher.ts +2 -1
  146. package/src/core/BaseAudioContext.ts +4 -6
  147. package/src/errors/AudioApiError.ts +8 -0
  148. package/src/errors/index.ts +1 -0
  149. package/src/interfaces.ts +1 -1
  150. package/src/specs/NativeAudioAPIModule.ts +5 -15
  151. package/src/specs/NativeAudioAPIModule.web.ts +1 -12
  152. package/src/system/notification/PlaybackNotificationManager.ts +42 -117
  153. package/src/system/notification/RecordingNotificationManager.ios.ts +65 -0
  154. package/src/system/notification/RecordingNotificationManager.ts +33 -183
  155. package/src/system/notification/index.ts +0 -1
  156. package/src/system/notification/types.ts +15 -37
  157. package/src/types.ts +2 -0
  158. package/src/utils/index.ts +3 -2
  159. package/src/utils/paths.ts +11 -0
  160. package/src/web-core/AudioContext.tsx +34 -19
  161. package/src/web-core/BaseAudioContext.tsx +9 -7
  162. package/src/web-system/notification/PlaybackNotificationManager.ts +1 -7
  163. package/src/web-system/notification/RecordingNotificationManager.ts +1 -16
  164. package/android/src/main/java/com/swmansion/audioapi/core/NativeAudioPlayer.kt +0 -26
  165. package/android/src/main/java/com/swmansion/audioapi/core/NativeAudioRecorder.kt +0 -26
  166. package/android/src/main/java/com/swmansion/audioapi/system/notification/SimpleNotification.kt +0 -119
  167. package/lib/commonjs/system/notification/SimpleNotificationManager.js +0 -125
  168. package/lib/commonjs/system/notification/SimpleNotificationManager.js.map +0 -1
  169. package/lib/module/system/notification/SimpleNotificationManager.js +0 -121
  170. package/lib/module/system/notification/SimpleNotificationManager.js.map +0 -1
  171. package/lib/typescript/system/notification/SimpleNotificationManager.d.ts +0 -21
  172. package/lib/typescript/system/notification/SimpleNotificationManager.d.ts.map +0 -1
  173. package/src/system/notification/SimpleNotificationManager.ts +0 -175
@@ -2,6 +2,7 @@ package com.swmansion.audioapi.system.notification
2
2
 
3
3
  import android.app.Notification
4
4
  import android.util.Log
5
+ import androidx.annotation.RequiresPermission
5
6
  import androidx.core.app.NotificationManagerCompat
6
7
  import com.facebook.react.bridge.ReactApplicationContext
7
8
  import com.facebook.react.bridge.ReadableMap
@@ -10,9 +11,11 @@ import java.lang.ref.WeakReference
10
11
 
11
12
  /**
12
13
  * Central notification registry that manages multiple notification instances.
14
+ * Automatically handles foreground service lifecycle based on active notifications.
13
15
  */
14
16
  class NotificationRegistry(
15
17
  private val reactContext: WeakReference<ReactApplicationContext>,
18
+ private val audioAPIModule: WeakReference<com.swmansion.audioapi.AudioAPIModule>,
16
19
  ) {
17
20
  companion object {
18
21
  private const val TAG = "NotificationRegistry"
@@ -27,29 +30,26 @@ class NotificationRegistry(
27
30
  private val activeNotifications = mutableMapOf<String, Boolean>()
28
31
 
29
32
  /**
30
- * Register a new notification instance.
31
- *
32
- * @param key Unique identifier for this notification
33
- * @param notification The notification instance to register
34
- */
35
- fun registerNotification(
36
- key: String,
37
- notification: BaseNotification,
38
- ) {
39
- notifications[key] = notification
40
- Log.d(TAG, "Registered notification: $key")
41
- }
42
-
43
- /**
44
- * Initialize and show a notification.
33
+ * Show or update a notification.
34
+ * Automatically creates the notification instance on first call.
35
+ * If notification is not visible, it will be shown and subscribed to foreground service.
36
+ * If already visible, it will be updated.
45
37
  *
46
38
  * @param key The unique identifier of the notification
39
+ * @param type The type of notification (only used for first creation)
47
40
  * @param options Configuration options from JavaScript
48
41
  */
42
+ @RequiresPermission(android.Manifest.permission.POST_NOTIFICATIONS)
49
43
  fun showNotification(
50
44
  key: String,
45
+ type: String,
51
46
  options: ReadableMap?,
52
47
  ) {
48
+ // Auto-create notification if it doesn't exist
49
+ if (!notifications.containsKey(key)) {
50
+ createNotification(type, key)
51
+ }
52
+
53
53
  val notification = notifications[key]
54
54
  if (notification == null) {
55
55
  Log.w(TAG, "Notification not found: $key")
@@ -57,85 +57,103 @@ class NotificationRegistry(
57
57
  }
58
58
 
59
59
  try {
60
- val builtNotification = notification.init(options)
61
- displayNotification(notification.getNotificationId(), builtNotification)
62
- activeNotifications[key] = true
60
+ val wasActive = isNotificationActive(key)
63
61
 
64
- // Subscribe to foreground service for persistent notifications
65
- ForegroundServiceManager.subscribe("notification_$key")
62
+ // Build/update the notification
63
+ val builtNotification = notification.show(options)
64
+ displayNotification(notification.getNotificationId(), builtNotification)
66
65
 
67
- Log.d(TAG, "Showing notification: $key")
66
+ // Subscribe to foreground service if not already active
67
+ if (!wasActive) {
68
+ ForegroundServiceManager.subscribe(notification)
69
+ activeNotifications[key] = true
70
+ Log.d(TAG, "Showing notification: $key (subscribed to foreground service)")
71
+ } else {
72
+ Log.d(TAG, "Updating notification: $key")
73
+ }
68
74
  } catch (e: Exception) {
69
75
  Log.e(TAG, "Error showing notification $key: ${e.message}", e)
70
76
  }
71
77
  }
72
78
 
73
79
  /**
74
- * Update an existing notification with new options.
80
+ * Hide a notification.
75
81
  *
76
82
  * @param key The unique identifier of the notification
77
- * @param options New configuration options from JavaScript
78
83
  */
79
- fun updateNotification(
80
- key: String,
81
- options: ReadableMap?,
82
- ) {
83
- if (!activeNotifications.getOrDefault(key, false)) {
84
- Log.w(TAG, "Cannot update inactive notification: $key")
85
- return
86
- }
87
-
84
+ fun hideNotification(key: String) {
88
85
  val notification = notifications[key]
89
86
  if (notification == null) {
90
- Log.w(TAG, "Notification not found: $key")
87
+ // Silently ignore if notification doesn't exist
91
88
  return
92
89
  }
93
90
 
94
91
  try {
95
- val builtNotification = notification.update(options)
96
- displayNotification(notification.getNotificationId(), builtNotification)
97
- Log.d(TAG, "Updated notification: $key")
92
+ // Only hide if currently active
93
+ if (activeNotifications.getOrDefault(key, false)) {
94
+ cancelNotification(notification.getNotificationId())
95
+ notification.hide()
96
+ activeNotifications[key] = false
97
+
98
+ // Unsubscribe from foreground service
99
+ ForegroundServiceManager.unsubscribe(notification)
100
+
101
+ Log.d(TAG, "Hiding notification: $key (unsubscribed from foreground service)")
102
+ }
98
103
  } catch (e: Exception) {
99
- Log.e(TAG, "Error updating notification $key: ${e.message}", e)
104
+ Log.e(TAG, "Error hiding notification $key: ${e.message}", e)
100
105
  }
101
106
  }
102
107
 
103
108
  /**
104
- * Hide and reset a notification.
109
+ * Create a notification instance.
105
110
  *
106
- * @param key The unique identifier of the notification
111
+ * @param type The type of notification to create
112
+ * @param key Unique identifier for this notification
107
113
  */
108
- fun hideNotification(key: String) {
109
- val notification = notifications[key]
110
- if (notification == null) {
111
- Log.w(TAG, "Notification not found: $key")
112
- return
113
- }
114
-
115
- try {
116
- cancelNotification(notification.getNotificationId())
117
- notification.reset()
118
- activeNotifications[key] = false
119
-
120
- // Unsubscribe from foreground service
121
- ForegroundServiceManager.unsubscribe("notification_$key")
114
+ private fun createNotification(
115
+ type: String,
116
+ key: String,
117
+ ) {
118
+ val notification =
119
+ when (type) {
120
+ "playback" -> {
121
+ PlaybackNotification(
122
+ reactContext,
123
+ audioAPIModule,
124
+ PlaybackNotification.ID,
125
+ "audio_playback",
126
+ )
127
+ }
128
+
129
+ "recording" -> {
130
+ RecordingNotification(
131
+ reactContext,
132
+ audioAPIModule,
133
+ RecordingNotification.ID,
134
+ "audio_recording4",
135
+ )
136
+ }
137
+
138
+ else -> {
139
+ throw IllegalArgumentException("Unknown notification type: $type")
140
+ }
141
+ }
122
142
 
123
- Log.d(TAG, "Hiding notification: $key")
124
- } catch (e: Exception) {
125
- Log.e(TAG, "Error hiding notification $key: ${e.message}", e)
126
- }
143
+ notifications[key] = notification
144
+ Log.d(TAG, "Created notification: $key (type: $type)")
127
145
  }
128
146
 
129
147
  /**
130
- * Unregister and cleanup a notification.
148
+ * Destroy and cleanup a notification.
131
149
  *
132
150
  * @param key The unique identifier of the notification
133
151
  */
134
- fun unregisterNotification(key: String) {
152
+ fun destroyNotification(key: String) {
135
153
  hideNotification(key)
136
154
  notifications.remove(key)
137
155
  activeNotifications.remove(key)
138
- Log.d(TAG, "Unregistered notification: $key")
156
+ Log.d(TAG, "Destroyed notification: $key")
139
157
  }
140
158
 
141
159
  /**
@@ -165,6 +183,7 @@ class NotificationRegistry(
165
183
  Log.d(TAG, "Cleaned up all notifications")
166
184
  }
167
185
 
186
+ @RequiresPermission(android.Manifest.permission.POST_NOTIFICATIONS)
168
187
  private fun displayNotification(
169
188
  id: Int,
170
189
  notification: Notification,