@stream-io/video-react-native-sdk 1.45.1 → 2.0.0-beta.1
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.
- package/CHANGELOG.md +5 -8
- package/README.md +15 -0
- package/android/src/main/java/com/streamvideo/reactnative/audio/AudioDeviceManager.kt +58 -110
- package/android/src/main/java/com/streamvideo/reactnative/callmanager/StreamInCallManagerModule.kt +5 -16
- package/dist/commonjs/utils/StreamVideoRN/index.js +0 -23
- package/dist/commonjs/utils/StreamVideoRN/index.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/commonjs/version.js.map +1 -1
- package/dist/module/utils/StreamVideoRN/index.js +0 -23
- package/dist/module/utils/StreamVideoRN/index.js.map +1 -1
- package/dist/module/version.js +1 -1
- package/dist/module/version.js.map +1 -1
- package/dist/typescript/utils/StreamVideoRN/index.d.ts +0 -13
- package/dist/typescript/utils/StreamVideoRN/index.d.ts.map +1 -1
- package/dist/typescript/version.d.ts +1 -1
- package/dist/typescript/version.d.ts.map +1 -1
- package/package.json +9 -9
- package/src/modules/call-manager/native-module.d.ts +0 -14
- package/src/utils/StreamVideoRN/index.ts +0 -27
- package/src/version.ts +1 -1
- package/android/src/main/java/com/streamvideo/reactnative/audio/CommunicationModeKeepAlive.kt +0 -247
package/CHANGELOG.md
CHANGED
|
@@ -2,22 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
-
## [
|
|
5
|
+
## [2.0.0-beta.1](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-native-sdk-2.0.0-beta.0...@stream-io/video-react-native-sdk-2.0.0-beta.1) (2026-09-04)
|
|
6
6
|
|
|
7
|
-
###
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- **react-native-sdk:** publish the corrected satellite peer ranges ([15172ec](https://github.com/GetStream/stream-video-js/commit/15172ec5a2e96ec7ad62c83be631776a9f315485)), closes [#2414](https://github.com/GetStream/stream-video-js/issues/2414)
|
|
8
10
|
|
|
9
|
-
-
|
|
10
|
-
- `@stream-io/video-client` updated to version `1.59.1`
|
|
11
|
-
- **client:** isolate coordinator event listener errors from the dispatch loop ([#2404](https://github.com/GetStream/stream-video-js/issues/2404)) ([4ab49de](https://github.com/GetStream/stream-video-js/commit/4ab49decc4bbc70b0fc35d6b92f2bd18922a105c)), closes [GetStream/stream-chat-js#1850](https://github.com/GetStream/stream-chat-js/issues/1850)
|
|
12
|
-
- **client:** keep passive participants out of the spotlight ([#2405](https://github.com/GetStream/stream-video-js/issues/2405)) ([0713650](https://github.com/GetStream/stream-video-js/commit/0713650fa90caa8a82ce0bee75acf4dbaaad33e9))
|
|
13
|
-
- `@stream-io/video-react-bindings` updated to version `1.20.2`
|
|
11
|
+
## [2.0.0-beta.0](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-native-sdk-1.45.0...@stream-io/video-react-native-sdk-2.0.0-beta.0) (2026-09-04)
|
|
14
12
|
|
|
15
13
|
### Bug Fixes
|
|
16
14
|
|
|
17
15
|
- **callingx:** don't tear down concurrent calls on stop service ([#2394](https://github.com/GetStream/stream-video-js/issues/2394)) ([d6e9deb](https://github.com/GetStream/stream-video-js/commit/d6e9debbe98ae91cc349f010eb92f76b35a3f932))
|
|
18
16
|
- **rn:** auto-leave previous callingx calls on new join ([#2402](https://github.com/GetStream/stream-video-js/issues/2402)) ([5a3dfdd](https://github.com/GetStream/stream-video-js/commit/5a3dfddd8ddbfacf6e8ea109656be82da91a3436))
|
|
19
17
|
- **rn:** wrong expo plugin Android call-alive foreground service detection ([#2398](https://github.com/GetStream/stream-video-js/issues/2398)) ([eac10b5](https://github.com/GetStream/stream-video-js/commit/eac10b5a390f6949b25535d2b4c4cf9bc3d5f065))
|
|
20
|
-
- workaround for android non-telecom path MODE_IN_COMMUNICATION reset edge-case ([#2360](https://github.com/GetStream/stream-video-js/issues/2360)) ([65a1fb7](https://github.com/GetStream/stream-video-js/commit/65a1fb766461f95a3b70fe221e9ace0caad6c64b))
|
|
21
18
|
|
|
22
19
|
## [1.45.0](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-native-sdk-1.44.0...@stream-io/video-react-native-sdk-1.45.0) (2026-08-28)
|
|
23
20
|
|
package/README.md
CHANGED
|
@@ -79,6 +79,21 @@ The monorepo consists of multiple folders, the most important of which are `pack
|
|
|
79
79
|
Before running this project please ensure you have set up your [development environment for React Native](https://reactnative.dev/docs/environment-setup).
|
|
80
80
|
The Stream Video React Native SDK supports apps created with the React Native CLI.
|
|
81
81
|
|
|
82
|
+
### Optional native add-ons
|
|
83
|
+
|
|
84
|
+
Noise cancellation, video filters and CallKit/Telecom ringing ship as separate
|
|
85
|
+
optional peer packages. On the `2.0.0-beta` line they are published on their own
|
|
86
|
+
`1.0.0-beta` line under the `beta` npm tag, so install them from that tag:
|
|
87
|
+
|
|
88
|
+
```sh
|
|
89
|
+
yarn add @stream-io/noise-cancellation-react-native@beta
|
|
90
|
+
yarn add @stream-io/video-filters-react-native@beta
|
|
91
|
+
yarn add @stream-io/react-native-callingx@beta
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Installing the `latest` builds of these packages alongside the v2 beta pulls the
|
|
95
|
+
v1 line and will report an unmet peer dependency.
|
|
96
|
+
|
|
82
97
|
## **Contributing** 🤝
|
|
83
98
|
|
|
84
99
|
- How can I submit a sample app?
|
|
@@ -107,30 +107,6 @@ class AudioDeviceManager(
|
|
|
107
107
|
*/
|
|
108
108
|
var telecomManagedMode: Boolean = false
|
|
109
109
|
|
|
110
|
-
/**
|
|
111
|
-
* Opt-out for the Android 11+ communication-mode keep-alive. Sticky developer preference —
|
|
112
|
-
* intentionally NOT reset in [stop], unlike the per-call fields above.
|
|
113
|
-
*/
|
|
114
|
-
var disableCommunicationModeWorkaround: Boolean = false
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* True once [stop]/[close] have torn routing down, until the next [start].
|
|
118
|
-
*
|
|
119
|
-
* [updateAudioDeviceState] is enqueued from off-thread sources (Bluetooth receivers,
|
|
120
|
-
* audio-focus and device callbacks), so a task can still land after teardown. Re-routing
|
|
121
|
-
* then would re-assert MODE_IN_COMMUNICATION via AudioManagerUtil, undoing the
|
|
122
|
-
* MODE_NORMAL restore in [stop]. Audio-thread confined.
|
|
123
|
-
*/
|
|
124
|
-
private var routingStopped = false
|
|
125
|
-
|
|
126
|
-
/** Keeps MODE_IN_COMMUNICATION owned for the whole Communicator call on Android 11+. */
|
|
127
|
-
private val communicationModeKeepAlive: CommunicationModeKeepAlive =
|
|
128
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
129
|
-
SilentPlaybackKeepAlive(mReactContext)
|
|
130
|
-
} else {
|
|
131
|
-
NoCommunicationModeKeepAlive
|
|
132
|
-
}
|
|
133
|
-
|
|
134
110
|
val bluetoothManager = BluetoothManager(mReactContext, this)
|
|
135
111
|
|
|
136
112
|
private val proximityManager by lazy { ProximityManager(mReactContext, this) }
|
|
@@ -154,64 +130,53 @@ class AudioDeviceManager(
|
|
|
154
130
|
audioFocusUtil.setup(callAudioRole, mReactContext)
|
|
155
131
|
}
|
|
156
132
|
|
|
157
|
-
/** Runs inline; callers must already be on the audio thread (see [runInAudioThread]). */
|
|
158
133
|
fun start(activity: Activity) {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
134
|
+
runInAudioThread {
|
|
135
|
+
setup()
|
|
136
|
+
selectedAudioDeviceEndpoint = null
|
|
137
|
+
if (callAudioRole == CallAudioRole.Communicator) {
|
|
138
|
+
// Audio routing is manually controlled by the SDK in communication media mode
|
|
139
|
+
// and local microphone can be published
|
|
140
|
+
activity.volumeControlStream = AudioManager.STREAM_VOICE_CALL
|
|
141
|
+
if (!telecomManagedMode) {
|
|
142
|
+
// Telecom owns routing/focus; only run our own routing when not Telecom-managed.
|
|
143
|
+
bluetoothManager.start()
|
|
144
|
+
mAudioManager.registerAudioDeviceCallback(this, null)
|
|
145
|
+
updateAudioDeviceState()
|
|
146
|
+
}
|
|
147
|
+
proximityManager.start()
|
|
148
|
+
} else {
|
|
149
|
+
activity.volumeControlStream = AudioManager.USE_DEFAULT_STREAM_TYPE
|
|
150
|
+
}
|
|
166
151
|
if (!telecomManagedMode) {
|
|
167
|
-
|
|
168
|
-
bluetoothManager.start()
|
|
169
|
-
mAudioManager.registerAudioDeviceCallback(this, null)
|
|
170
|
-
updateAudioDeviceState()
|
|
152
|
+
audioFocusUtil.requestFocus(callAudioRole, mReactContext)
|
|
171
153
|
}
|
|
172
|
-
proximityManager.start()
|
|
173
|
-
} else {
|
|
174
|
-
activity.volumeControlStream = AudioManager.USE_DEFAULT_STREAM_TYPE
|
|
175
|
-
}
|
|
176
|
-
if (!telecomManagedMode) {
|
|
177
|
-
audioFocusUtil.requestFocus(callAudioRole, mReactContext)
|
|
178
|
-
}
|
|
179
|
-
// Started last, after focus/routing, so the silent track uses the correct route.
|
|
180
|
-
if (callAudioRole == CallAudioRole.Communicator &&
|
|
181
|
-
!telecomManagedMode &&
|
|
182
|
-
!disableCommunicationModeWorkaround
|
|
183
|
-
) {
|
|
184
|
-
communicationModeKeepAlive.start()
|
|
185
154
|
}
|
|
186
155
|
}
|
|
187
156
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
157
|
+
fun stop(activity: Activity) {
|
|
158
|
+
runInAudioThread {
|
|
159
|
+
if (callAudioRole == CallAudioRole.Communicator) {
|
|
160
|
+
if (!telecomManagedMode) {
|
|
161
|
+
// Only tear down what we set up ourselves; Telecom owns its own teardown.
|
|
162
|
+
if (Build.VERSION.SDK_INT >= 31) {
|
|
163
|
+
mAudioManager.clearCommunicationDevice()
|
|
164
|
+
} else {
|
|
165
|
+
mAudioManager.setSpeakerphoneOn(false)
|
|
166
|
+
}
|
|
167
|
+
bluetoothManager.stop()
|
|
199
168
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
169
|
+
callAudioRole = CallAudioRole.Communicator
|
|
170
|
+
enableStereo = false
|
|
171
|
+
defaultAudioDevice = AudioDeviceEndpoint.TYPE_SPEAKER
|
|
172
|
+
proximityManager.stop()
|
|
204
173
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
activity?.volumeControlStream = AudioManager.USE_DEFAULT_STREAM_TYPE
|
|
211
|
-
if (!telecomManagedMode) {
|
|
212
|
-
audioFocusUtil.abandonFocus()
|
|
174
|
+
activity.volumeControlStream = AudioManager.USE_DEFAULT_STREAM_TYPE
|
|
175
|
+
if (!telecomManagedMode) {
|
|
176
|
+
audioFocusUtil.abandonFocus()
|
|
177
|
+
}
|
|
178
|
+
telecomManagedMode = false
|
|
213
179
|
}
|
|
214
|
-
telecomManagedMode = false
|
|
215
180
|
}
|
|
216
181
|
|
|
217
182
|
fun setMicrophoneMute(enable: Boolean) {
|
|
@@ -263,9 +228,6 @@ class AudioDeviceManager(
|
|
|
263
228
|
}
|
|
264
229
|
|
|
265
230
|
private fun switchDeviceEndpointType(@EndpointType deviceType: Int) {
|
|
266
|
-
// Sole sink for routing changes, and AudioManagerUtil re-asserts MODE_IN_COMMUNICATION
|
|
267
|
-
// here — so late work of any origin must not reach it after teardown.
|
|
268
|
-
if (routingStopped) return
|
|
269
231
|
val newDevice = AudioManagerUtil.switchDeviceEndpointType(
|
|
270
232
|
deviceType,
|
|
271
233
|
mEndpointMaps,
|
|
@@ -275,49 +237,38 @@ class AudioDeviceManager(
|
|
|
275
237
|
this.selectedAudioDeviceEndpoint = newDevice
|
|
276
238
|
}
|
|
277
239
|
|
|
278
|
-
/** Runs inline; callers must already be on the audio thread (see [runInAudioThread]). */
|
|
279
240
|
fun switchDeviceById(
|
|
280
241
|
deviceId: String
|
|
281
242
|
) {
|
|
282
243
|
Log.d(TAG, "switchDeviceById: deviceId = $deviceId")
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
)
|
|
296
|
-
}
|
|
297
|
-
} else {
|
|
298
|
-
val endpoint = nonBluetoothEndpointById(deviceId)
|
|
299
|
-
if (endpoint != null) {
|
|
300
|
-
switchDeviceEndpointType(endpoint.type)
|
|
244
|
+
runInAudioThread {
|
|
245
|
+
val btDevice = mEndpointMaps.bluetoothEndpoints[deviceId]
|
|
246
|
+
if (btDevice != null) {
|
|
247
|
+
if (Build.VERSION.SDK_INT >= 31) {
|
|
248
|
+
mAudioManager.setCommunicationDevice(btDevice.deviceInfo)
|
|
249
|
+
bluetoothManager.updateDevice()
|
|
250
|
+
this.selectedAudioDeviceEndpoint = btDevice
|
|
251
|
+
} else {
|
|
252
|
+
switchDeviceEndpointType(
|
|
253
|
+
AudioDeviceEndpoint.TYPE_BLUETOOTH
|
|
254
|
+
)
|
|
255
|
+
}
|
|
301
256
|
} else {
|
|
302
|
-
|
|
257
|
+
val endpoint = nonBluetoothEndpointById(deviceId)
|
|
258
|
+
if (endpoint != null) {
|
|
259
|
+
switchDeviceEndpointType(endpoint.type)
|
|
260
|
+
} else {
|
|
261
|
+
Log.e(TAG, "switchDeviceById: no endpoint found for id $deviceId")
|
|
262
|
+
}
|
|
303
263
|
}
|
|
304
264
|
}
|
|
305
265
|
}
|
|
306
266
|
|
|
307
267
|
override fun close() {
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
runInAudioThread {
|
|
311
|
-
routingStopped = true
|
|
312
|
-
communicationModeKeepAlive.release()
|
|
313
|
-
mAudioManager.unregisterAudioDeviceCallback(this)
|
|
314
|
-
proximityManager.onDestroy()
|
|
315
|
-
}
|
|
268
|
+
mAudioManager.unregisterAudioDeviceCallback(this)
|
|
269
|
+
proximityManager.onDestroy()
|
|
316
270
|
}
|
|
317
271
|
|
|
318
|
-
/** Short description of the keep-alive state, for the audio debug log. */
|
|
319
|
-
fun communicationModeKeepAliveState(): String = communicationModeKeepAlive.describeState()
|
|
320
|
-
|
|
321
272
|
override fun onAudioDevicesAdded(addedDevices: Array<out AudioDeviceInfo>?) {
|
|
322
273
|
if (addedDevices != null) {
|
|
323
274
|
runInAudioThread {
|
|
@@ -472,9 +423,6 @@ class AudioDeviceManager(
|
|
|
472
423
|
*/
|
|
473
424
|
fun updateAudioDeviceState() {
|
|
474
425
|
runInAudioThread {
|
|
475
|
-
// Bail early: on API < 31 bluetoothState survives stop(), so a late pass could
|
|
476
|
-
// still start SCO after the call ended.
|
|
477
|
-
if (routingStopped) return@runInAudioThread
|
|
478
426
|
if (telecomManagedMode) {
|
|
479
427
|
// Telecom is the single source of truth for routing/endpoints in this mode.
|
|
480
428
|
return@runInAudioThread
|
package/android/src/main/java/com/streamvideo/reactnative/callmanager/StreamInCallManagerModule.kt
CHANGED
|
@@ -75,18 +75,6 @@ class StreamInCallManagerModule(reactContext: ReactApplicationContext) :
|
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
@ReactMethod
|
|
79
|
-
fun setDisableCommunicationModeWorkaround(disabled: Boolean) {
|
|
80
|
-
AudioDeviceManager.runInAudioThread {
|
|
81
|
-
if (audioManagerActivated) {
|
|
82
|
-
Log.e(TAG, "setDisableCommunicationModeWorkaround(): AudioManager is already activated and so it cannot be changed")
|
|
83
|
-
return@runInAudioThread
|
|
84
|
-
}
|
|
85
|
-
Log.d(TAG, "setDisableCommunicationModeWorkaround(): $disabled")
|
|
86
|
-
mAudioDeviceManager.disableCommunicationModeWorkaround = disabled
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
78
|
@ReactMethod
|
|
91
79
|
fun setDefaultAudioDeviceEndpointType(endpointDeviceTypeName: String) {
|
|
92
80
|
AudioDeviceManager.runInAudioThread {
|
|
@@ -141,8 +129,10 @@ class StreamInCallManagerModule(reactContext: ReactApplicationContext) :
|
|
|
141
129
|
AudioDeviceManager.runInAudioThread {
|
|
142
130
|
if (audioManagerActivated) {
|
|
143
131
|
Log.d(TAG, "stop() mAudioDeviceManager")
|
|
144
|
-
|
|
145
|
-
|
|
132
|
+
reactApplicationContext.currentActivity?.let {
|
|
133
|
+
mAudioDeviceManager.stop(it)
|
|
134
|
+
audioManagerActivated = false
|
|
135
|
+
}
|
|
146
136
|
setMicrophoneMute(false)
|
|
147
137
|
setKeepScreenOn(false)
|
|
148
138
|
}
|
|
@@ -195,8 +185,7 @@ class StreamInCallManagerModule(reactContext: ReactApplicationContext) :
|
|
|
195
185
|
|
|
196
186
|
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
197
187
|
fun getAudioStateLog(): String {
|
|
198
|
-
return WebRtcAudioUtils.getAudioStateLog(reactApplicationContext)
|
|
199
|
-
"Communication mode keep-alive: ${mAudioDeviceManager.communicationModeKeepAliveState()}\n"
|
|
188
|
+
return WebRtcAudioUtils.getAudioStateLog(reactApplicationContext)
|
|
200
189
|
}
|
|
201
190
|
|
|
202
191
|
@Suppress("unused")
|
|
@@ -131,29 +131,6 @@ class StreamVideoRN {
|
|
|
131
131
|
_pushLogoutCallback.default.current = [];
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
/**
|
|
135
|
-
* Android only. Opt out of the Android 11+ communication-mode keep-alive.
|
|
136
|
-
*
|
|
137
|
-
* By default the SDK plays a silent voice-communication track for the duration of a
|
|
138
|
-
* communicator-role call, so Android does not reset `MODE_IN_COMMUNICATION` ~6s after it is
|
|
139
|
-
* set (which breaks audio routing and echo cancellation).
|
|
140
|
-
* See {@link https://issuetracker.google.com/issues/209493718}
|
|
141
|
-
*
|
|
142
|
-
* Call this at app start, alongside {@link setPushConfig} — the native audio manager
|
|
143
|
-
* rejects the change once it has been activated for a call. No-op on iOS and on
|
|
144
|
-
* Android below API 30.
|
|
145
|
-
*/
|
|
146
|
-
static setDisableCommunicationModeWorkaround(disabled) {
|
|
147
|
-
if (_reactNative.Platform.OS !== 'android') {
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
try {
|
|
151
|
-
_reactNative.NativeModules.StreamInCallManager?.setDisableCommunicationModeWorkaround(disabled);
|
|
152
|
-
} catch (error) {
|
|
153
|
-
_videoClient.videoLoggerSystem.getLogger('StreamVideoRN').warn('setDisableCommunicationModeWorkaround failed', error);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
134
|
/**
|
|
158
135
|
* Play native busy tone for call rejection
|
|
159
136
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_pushLogoutCallback","_interopRequireDefault","require","_setupIosVoipPushEvents","_setupAndroidPushEvents","_setupCallingExpEvents","_callingx","_reactNative","_videoClient","e","__esModule","default","deepMerge","target","source","result","key","undefined","Array","isArray","DEFAULT_STREAM_VIDEO_CONFIG","foregroundService","android","channel","id","name","notificationTexts","title","body","taskToRun","Promise","StreamVideoRN","config","updateConfig","setPushConfig","pushConfig","push","callingx","getCallingxLib","videoLoggerSystem","getLogger","info","JSON","stringify","options","extractCallingExpOptions","setup","Error","setupCallingExpEvents","setupIosVoipPushEvents","setupAndroidPushEvents","getConfig","onPushLogout","callbacks","pushLogoutCallbacks","current","resolve","all","map","callback","then","clearPushLogoutCallbacks","
|
|
1
|
+
{"version":3,"names":["_pushLogoutCallback","_interopRequireDefault","require","_setupIosVoipPushEvents","_setupAndroidPushEvents","_setupCallingExpEvents","_callingx","_reactNative","_videoClient","e","__esModule","default","deepMerge","target","source","result","key","undefined","Array","isArray","DEFAULT_STREAM_VIDEO_CONFIG","foregroundService","android","channel","id","name","notificationTexts","title","body","taskToRun","Promise","StreamVideoRN","config","updateConfig","setPushConfig","pushConfig","push","callingx","getCallingxLib","videoLoggerSystem","getLogger","info","JSON","stringify","options","extractCallingExpOptions","setup","Error","setupCallingExpEvents","setupIosVoipPushEvents","setupAndroidPushEvents","getConfig","onPushLogout","callbacks","pushLogoutCallbacks","current","resolve","all","map","callback","then","clearPushLogoutCallbacks","playBusyTone","NativeModules","StreamVideoReactNative","stopBusyTone","androidHasAudioOutputHardware","Platform","OS","hasAudioOutputHardware","androidHasMicrophoneHardware","hasMicrophoneHardware","androidHasCameraHardware","hasCameraHardware","exports"],"sourceRoot":"../../../../src","sources":["utils/StreamVideoRN/index.ts"],"mappings":"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","ignoreList":[]}
|
package/dist/commonjs/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["version","exports"],"sourceRoot":"../../src","sources":["version.ts"],"mappings":";;;;;;AAAO,MAAMA,OAAO,GAAAC,OAAA,CAAAD,OAAA,GAAG,
|
|
1
|
+
{"version":3,"names":["version","exports"],"sourceRoot":"../../src","sources":["version.ts"],"mappings":";;;;;;AAAO,MAAMA,OAAO,GAAAC,OAAA,CAAAD,OAAA,GAAG,cAAc","ignoreList":[]}
|
|
@@ -127,29 +127,6 @@ export class StreamVideoRN {
|
|
|
127
127
|
pushLogoutCallbacks.current = [];
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
/**
|
|
131
|
-
* Android only. Opt out of the Android 11+ communication-mode keep-alive.
|
|
132
|
-
*
|
|
133
|
-
* By default the SDK plays a silent voice-communication track for the duration of a
|
|
134
|
-
* communicator-role call, so Android does not reset `MODE_IN_COMMUNICATION` ~6s after it is
|
|
135
|
-
* set (which breaks audio routing and echo cancellation).
|
|
136
|
-
* See {@link https://issuetracker.google.com/issues/209493718}
|
|
137
|
-
*
|
|
138
|
-
* Call this at app start, alongside {@link setPushConfig} — the native audio manager
|
|
139
|
-
* rejects the change once it has been activated for a call. No-op on iOS and on
|
|
140
|
-
* Android below API 30.
|
|
141
|
-
*/
|
|
142
|
-
static setDisableCommunicationModeWorkaround(disabled) {
|
|
143
|
-
if (Platform.OS !== 'android') {
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
try {
|
|
147
|
-
NativeModules.StreamInCallManager?.setDisableCommunicationModeWorkaround(disabled);
|
|
148
|
-
} catch (error) {
|
|
149
|
-
videoLoggerSystem.getLogger('StreamVideoRN').warn('setDisableCommunicationModeWorkaround failed', error);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
130
|
/**
|
|
154
131
|
* Play native busy tone for call rejection
|
|
155
132
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["pushLogoutCallbacks","setupIosVoipPushEvents","setupAndroidPushEvents","setupCallingExpEvents","extractCallingExpOptions","getCallingxLib","NativeModules","Platform","videoLoggerSystem","deepMerge","target","source","result","key","undefined","Array","isArray","DEFAULT_STREAM_VIDEO_CONFIG","foregroundService","android","channel","id","name","notificationTexts","title","body","taskToRun","Promise","StreamVideoRN","config","updateConfig","setPushConfig","pushConfig","push","callingx","getLogger","info","JSON","stringify","options","setup","Error","getConfig","onPushLogout","callbacks","current","resolve","all","map","callback","then","clearPushLogoutCallbacks","
|
|
1
|
+
{"version":3,"names":["pushLogoutCallbacks","setupIosVoipPushEvents","setupAndroidPushEvents","setupCallingExpEvents","extractCallingExpOptions","getCallingxLib","NativeModules","Platform","videoLoggerSystem","deepMerge","target","source","result","key","undefined","Array","isArray","DEFAULT_STREAM_VIDEO_CONFIG","foregroundService","android","channel","id","name","notificationTexts","title","body","taskToRun","Promise","StreamVideoRN","config","updateConfig","setPushConfig","pushConfig","push","callingx","getLogger","info","JSON","stringify","options","setup","Error","getConfig","onPushLogout","callbacks","current","resolve","all","map","callback","then","clearPushLogoutCallbacks","playBusyTone","StreamVideoReactNative","stopBusyTone","androidHasAudioOutputHardware","OS","hasAudioOutputHardware","androidHasMicrophoneHardware","hasMicrophoneHardware","androidHasCameraHardware","hasCameraHardware"],"sourceRoot":"../../../../src","sources":["utils/StreamVideoRN/index.ts"],"mappings":"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","ignoreList":[]}
|
package/dist/module/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["version"],"sourceRoot":"../../src","sources":["version.ts"],"mappings":";;AAAA,OAAO,MAAMA,OAAO,GAAG,
|
|
1
|
+
{"version":3,"names":["version"],"sourceRoot":"../../src","sources":["version.ts"],"mappings":";;AAAA,OAAO,MAAMA,OAAO,GAAG,cAAc","ignoreList":[]}
|
|
@@ -54,19 +54,6 @@ export declare class StreamVideoRN {
|
|
|
54
54
|
*/
|
|
55
55
|
static onPushLogout(): Promise<void>;
|
|
56
56
|
static clearPushLogoutCallbacks(): void;
|
|
57
|
-
/**
|
|
58
|
-
* Android only. Opt out of the Android 11+ communication-mode keep-alive.
|
|
59
|
-
*
|
|
60
|
-
* By default the SDK plays a silent voice-communication track for the duration of a
|
|
61
|
-
* communicator-role call, so Android does not reset `MODE_IN_COMMUNICATION` ~6s after it is
|
|
62
|
-
* set (which breaks audio routing and echo cancellation).
|
|
63
|
-
* See {@link https://issuetracker.google.com/issues/209493718}
|
|
64
|
-
*
|
|
65
|
-
* Call this at app start, alongside {@link setPushConfig} — the native audio manager
|
|
66
|
-
* rejects the change once it has been activated for a call. No-op on iOS and on
|
|
67
|
-
* Android below API 30.
|
|
68
|
-
*/
|
|
69
|
-
static setDisableCommunicationModeWorkaround(disabled: boolean): void;
|
|
70
57
|
/**
|
|
71
58
|
* Play native busy tone for call rejection
|
|
72
59
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/StreamVideoRN/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAajD,KAAK,WAAW,CAAC,CAAC,IAAI;KACnB,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAChE,CAAC;AAgDF,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,MAAM,CAA+B;IAEpD;;;;OAIG;IACH,MAAM,CAAC,YAAY,CACjB,YAAY,EAAE,WAAW,CAAC,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;IAK5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;IACH,MAAM,CAAC,aAAa,CAAC,UAAU,EAAE,WAAW,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;IA0BvE,MAAM,CAAC,SAAS;IAIhB;;;OAGG;IACH,MAAM,CAAC,YAAY;IASnB,MAAM,CAAC,wBAAwB;IAI/B
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/StreamVideoRN/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAajD,KAAK,WAAW,CAAC,CAAC,IAAI;KACnB,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAChE,CAAC;AAgDF,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,MAAM,CAA+B;IAEpD;;;;OAIG;IACH,MAAM,CAAC,YAAY,CACjB,YAAY,EAAE,WAAW,CAAC,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;IAK5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;IACH,MAAM,CAAC,aAAa,CAAC,UAAU,EAAE,WAAW,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;IA0BvE,MAAM,CAAC,SAAS;IAIhB;;;OAGG;IACH,MAAM,CAAC,YAAY;IASnB,MAAM,CAAC,wBAAwB;IAI/B;;OAEG;WACU,YAAY;IAIzB;;OAEG;WACU,YAAY;IAIzB;;;OAGG;WACU,6BAA6B,IAAI,OAAO,CAAC,OAAO,CAAC;IAQ9D;;;OAGG;WACU,4BAA4B,IAAI,OAAO,CAAC,OAAO,CAAC;IAQ7D;;;OAGG;WACU,wBAAwB,IAAI,OAAO,CAAC,OAAO,CAAC;CAO1D"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const version = "
|
|
1
|
+
export declare const version = "2.0.0-beta.1";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,iBAAiB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stream-io/video-react-native-sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-beta.1",
|
|
4
4
|
"description": "Stream Video SDK for React Native",
|
|
5
5
|
"author": "https://getstream.io",
|
|
6
6
|
"homepage": "https://getstream.io/video/docs/react-native/",
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
"!**/.*"
|
|
53
53
|
],
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@stream-io/video-client": "
|
|
56
|
-
"@stream-io/video-react-bindings": "
|
|
55
|
+
"@stream-io/video-client": "2.0.0-beta.0",
|
|
56
|
+
"@stream-io/video-react-bindings": "2.0.0-beta.0",
|
|
57
57
|
"intl-pluralrules": "2.0.1",
|
|
58
58
|
"react-native-url-polyfill": "^3.0.0",
|
|
59
59
|
"rxjs": "~7.8.2",
|
|
@@ -63,10 +63,10 @@
|
|
|
63
63
|
"@react-native-community/netinfo": ">=9.0.0",
|
|
64
64
|
"@react-native-firebase/app": ">=17.5.0",
|
|
65
65
|
"@react-native-firebase/messaging": ">=17.5.0",
|
|
66
|
-
"@stream-io/noise-cancellation-react-native": ">=0.
|
|
67
|
-
"@stream-io/react-native-callingx": ">=0.
|
|
66
|
+
"@stream-io/noise-cancellation-react-native": ">=1.0.0-beta.0",
|
|
67
|
+
"@stream-io/react-native-callingx": ">=1.0.0-beta.0",
|
|
68
68
|
"@stream-io/react-native-webrtc": "^145.3.1",
|
|
69
|
-
"@stream-io/video-filters-react-native": ">=0.
|
|
69
|
+
"@stream-io/video-filters-react-native": ">=1.0.0-beta.0",
|
|
70
70
|
"expo": ">=47.0.0",
|
|
71
71
|
"expo-notifications": "*",
|
|
72
72
|
"react": ">=17.0.0",
|
|
@@ -117,11 +117,11 @@
|
|
|
117
117
|
"@react-native/babel-preset": "0.86.2",
|
|
118
118
|
"@react-native/jest-preset": "0.86.2",
|
|
119
119
|
"@react-native/metro-config": "0.86.2",
|
|
120
|
-
"@stream-io/noise-cancellation-react-native": "^0.
|
|
121
|
-
"@stream-io/react-native-callingx": "^0.
|
|
120
|
+
"@stream-io/noise-cancellation-react-native": "^1.0.0-beta.0",
|
|
121
|
+
"@stream-io/react-native-callingx": "^1.0.0-beta.0",
|
|
122
122
|
"@stream-io/react-native-webrtc": "145.3.1",
|
|
123
123
|
"@stream-io/typescript-config": "^0.0.0",
|
|
124
|
-
"@stream-io/video-filters-react-native": "^0.
|
|
124
|
+
"@stream-io/video-filters-react-native": "^1.0.0-beta.0",
|
|
125
125
|
"@testing-library/jest-native": "^5.4.3",
|
|
126
126
|
"@testing-library/react-native": "13.3.3",
|
|
127
127
|
"@tsconfig/node18": "^18.2.6",
|
|
@@ -32,20 +32,6 @@ export interface CallManager extends NativeModule {
|
|
|
32
32
|
*/
|
|
33
33
|
setTelecomManagedMode: (enabled: boolean) => void;
|
|
34
34
|
|
|
35
|
-
/**
|
|
36
|
-
* Opt out of the Android 11+ communication-mode keep-alive workaround.
|
|
37
|
-
*
|
|
38
|
-
* On Android 11+ (API 30) the OS resets `MODE_IN_COMMUNICATION` ~6s after it is
|
|
39
|
-
* set when there is no active voice-communication playback/recording, which
|
|
40
|
-
* breaks audio routing and AEC. By default the SDK plays a silent
|
|
41
|
-
* voice-communication track for the duration of a communicator-role call to
|
|
42
|
-
* prevent this. Pass `true` to disable it. Sticky for the process lifetime.
|
|
43
|
-
*
|
|
44
|
-
* No-op on iOS and on Android below API 30. See
|
|
45
|
-
* https://issuetracker.google.com/issues/209493718
|
|
46
|
-
*/
|
|
47
|
-
setDisableCommunicationModeWorkaround: (disabled: boolean) => void;
|
|
48
|
-
|
|
49
35
|
/**
|
|
50
36
|
* Choose an audio device endpoint by its stable id.
|
|
51
37
|
* @param deviceId - The id of the audio device to choose (`AudioDevice.id`).
|
|
@@ -158,33 +158,6 @@ export class StreamVideoRN {
|
|
|
158
158
|
pushLogoutCallbacks.current = [];
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
-
/**
|
|
162
|
-
* Android only. Opt out of the Android 11+ communication-mode keep-alive.
|
|
163
|
-
*
|
|
164
|
-
* By default the SDK plays a silent voice-communication track for the duration of a
|
|
165
|
-
* communicator-role call, so Android does not reset `MODE_IN_COMMUNICATION` ~6s after it is
|
|
166
|
-
* set (which breaks audio routing and echo cancellation).
|
|
167
|
-
* See {@link https://issuetracker.google.com/issues/209493718}
|
|
168
|
-
*
|
|
169
|
-
* Call this at app start, alongside {@link setPushConfig} — the native audio manager
|
|
170
|
-
* rejects the change once it has been activated for a call. No-op on iOS and on
|
|
171
|
-
* Android below API 30.
|
|
172
|
-
*/
|
|
173
|
-
static setDisableCommunicationModeWorkaround(disabled: boolean) {
|
|
174
|
-
if (Platform.OS !== 'android') {
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
try {
|
|
178
|
-
NativeModules.StreamInCallManager?.setDisableCommunicationModeWorkaround(
|
|
179
|
-
disabled,
|
|
180
|
-
);
|
|
181
|
-
} catch (error) {
|
|
182
|
-
videoLoggerSystem
|
|
183
|
-
.getLogger('StreamVideoRN')
|
|
184
|
-
.warn('setDisableCommunicationModeWorkaround failed', error);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
161
|
/**
|
|
189
162
|
* Play native busy tone for call rejection
|
|
190
163
|
*/
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '
|
|
1
|
+
export const version = '2.0.0-beta.1';
|
package/android/src/main/java/com/streamvideo/reactnative/audio/CommunicationModeKeepAlive.kt
DELETED
|
@@ -1,247 +0,0 @@
|
|
|
1
|
-
package com.streamvideo.reactnative.audio
|
|
2
|
-
|
|
3
|
-
import android.annotation.SuppressLint
|
|
4
|
-
import android.content.Context
|
|
5
|
-
import android.content.Context.AUDIO_SERVICE
|
|
6
|
-
import android.media.AudioAttributes
|
|
7
|
-
import android.media.AudioFormat
|
|
8
|
-
import android.media.AudioManager
|
|
9
|
-
import android.media.AudioTrack
|
|
10
|
-
import android.os.Build
|
|
11
|
-
import android.util.Log
|
|
12
|
-
import androidx.annotation.RequiresApi
|
|
13
|
-
import com.streamvideo.reactnative.callmanager.StreamInCallManagerModule
|
|
14
|
-
import java.nio.ByteBuffer
|
|
15
|
-
import java.util.concurrent.Executors
|
|
16
|
-
import java.util.concurrent.ScheduledExecutorService
|
|
17
|
-
import java.util.concurrent.TimeUnit
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Holds the audio system in [AudioManager.MODE_IN_COMMUNICATION] for the duration
|
|
21
|
-
* of a communicator-role call.
|
|
22
|
-
*
|
|
23
|
-
* Why this is needed: from Android 11 (API 30) the platform demotes the
|
|
24
|
-
* audio mode back to `MODE_NORMAL` about six seconds after `setMode()` unless the
|
|
25
|
-
* call is actively playing or recording on the voice-communication path.
|
|
26
|
-
* During a call whose microphone is muted and that has no inbound audio yet,
|
|
27
|
-
* neither condition is met, so routing silently falls back to the media path and
|
|
28
|
-
* hardware echo cancellation is switched off.
|
|
29
|
-
* Details: https://issuetracker.google.com/issues/209493718
|
|
30
|
-
*
|
|
31
|
-
* We satisfy the "actively playing" condition by continuously looping an inaudible
|
|
32
|
-
* audo track on the voice-communication stream, which keeps the platform counting us
|
|
33
|
-
* as an active player and therefore keeps the mode in place.
|
|
34
|
-
*/
|
|
35
|
-
interface CommunicationModeKeepAlive {
|
|
36
|
-
/** Begin holding the communication mode. Idempotent. */
|
|
37
|
-
fun start()
|
|
38
|
-
|
|
39
|
-
/** Stop holding the communication mode. Idempotent; the instance can be started again. */
|
|
40
|
-
fun stop()
|
|
41
|
-
|
|
42
|
-
/** Permanently release all resources. The instance must not be used afterwards. */
|
|
43
|
-
fun release()
|
|
44
|
-
|
|
45
|
-
/** Short human-readable state, surfaced in the audio-state debug log. */
|
|
46
|
-
fun describeState(): String
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/** No-op variant used on platforms where the mode reset does not occur (Android API < 30). */
|
|
50
|
-
object NoCommunicationModeKeepAlive : CommunicationModeKeepAlive {
|
|
51
|
-
override fun start() {}
|
|
52
|
-
override fun stop() {}
|
|
53
|
-
override fun release() {}
|
|
54
|
-
override fun describeState(): String = "disabled (android platform API < 30)"
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Default implementation backed by a silent, looping voice-communication
|
|
59
|
-
* [AudioTrack]. If the silent player cannot be created on a given device, it
|
|
60
|
-
* degrades to a lightweight poller that re-applies the mode whenever the platform
|
|
61
|
-
* has reset it.
|
|
62
|
-
*
|
|
63
|
-
* All lifecycle transitions and every access to [track] are serialized on [gate],
|
|
64
|
-
* so a play/pause can never overlap a release. The poller only ever touches the
|
|
65
|
-
* audio mode (never the track), so it runs lock-free.
|
|
66
|
-
*
|
|
67
|
-
* @suppress
|
|
68
|
-
*/
|
|
69
|
-
@RequiresApi(Build.VERSION_CODES.R)
|
|
70
|
-
internal class SilentPlaybackKeepAlive(
|
|
71
|
-
private val context: Context,
|
|
72
|
-
) : CommunicationModeKeepAlive {
|
|
73
|
-
|
|
74
|
-
private val gate = Any()
|
|
75
|
-
|
|
76
|
-
private var track: AudioTrack? = null
|
|
77
|
-
|
|
78
|
-
/** Whether we currently intend the silent player to be running. */
|
|
79
|
-
private var engaged = false
|
|
80
|
-
|
|
81
|
-
/** Read by the poller (off-gate) to drop ticks that were queued before we stopped. */
|
|
82
|
-
@Volatile
|
|
83
|
-
private var live = false
|
|
84
|
-
|
|
85
|
-
private var modePoller: ScheduledExecutorService? = null
|
|
86
|
-
|
|
87
|
-
override fun start(): Unit = synchronized(gate) {
|
|
88
|
-
live = true
|
|
89
|
-
if (engaged) return
|
|
90
|
-
engaged = true
|
|
91
|
-
|
|
92
|
-
val player = track ?: createSilentTrack()?.also { track = it }
|
|
93
|
-
if (player != null && player.state == AudioTrack.STATE_INITIALIZED && play(player)) {
|
|
94
|
-
return
|
|
95
|
-
}
|
|
96
|
-
// No usable silent player on this device — fall back to reactive repair.
|
|
97
|
-
player?.release()
|
|
98
|
-
track = null
|
|
99
|
-
startModePoller()
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Starts playback, reporting whether the track actually entered the playing state.
|
|
104
|
-
* `play()` can throw or leave the track stopped even from STATE_INITIALIZED; treating
|
|
105
|
-
* that as success would strand the keep-alive with neither a track nor the poller.
|
|
106
|
-
*/
|
|
107
|
-
private fun play(player: AudioTrack): Boolean =
|
|
108
|
-
try {
|
|
109
|
-
player.play()
|
|
110
|
-
player.playState == AudioTrack.PLAYSTATE_PLAYING
|
|
111
|
-
} catch (e: IllegalStateException) {
|
|
112
|
-
Log.w(TAG, "Silent keep-alive track refused to start.", e)
|
|
113
|
-
false
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
override fun stop() = synchronized(gate) {
|
|
117
|
-
live = false
|
|
118
|
-
if (engaged) {
|
|
119
|
-
engaged = false
|
|
120
|
-
track?.takeIf { it.state == AudioTrack.STATE_INITIALIZED }?.pause()
|
|
121
|
-
}
|
|
122
|
-
stopModePoller()
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
override fun release() = synchronized(gate) {
|
|
126
|
-
live = false
|
|
127
|
-
engaged = false
|
|
128
|
-
stopModePoller()
|
|
129
|
-
track?.let {
|
|
130
|
-
if (it.state == AudioTrack.STATE_INITIALIZED) it.pause()
|
|
131
|
-
it.release()
|
|
132
|
-
}
|
|
133
|
-
track = null
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
override fun describeState(): String = synchronized(gate) {
|
|
137
|
-
val playing = track?.playState == AudioTrack.PLAYSTATE_PLAYING
|
|
138
|
-
"enabled, engaged=$engaged, built=${track != null}, playing=$playing, " +
|
|
139
|
-
"modePoller=${modePoller != null}"
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
@SuppressLint("Range")
|
|
143
|
-
private fun createSilentTrack(): AudioTrack? {
|
|
144
|
-
return try {
|
|
145
|
-
val audioManager = context.getSystemService(AUDIO_SERVICE) as AudioManager
|
|
146
|
-
val sampleRate = positiveOrDefault(
|
|
147
|
-
audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE)?.toIntOrNull(),
|
|
148
|
-
DEFAULT_SAMPLE_RATE,
|
|
149
|
-
)
|
|
150
|
-
// One buffer worth of frames is enough — we loop it forever.
|
|
151
|
-
val frameCount = positiveOrDefault(
|
|
152
|
-
audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER)
|
|
153
|
-
?.toIntOrNull(),
|
|
154
|
-
sampleRate / 100, // ~10 ms
|
|
155
|
-
)
|
|
156
|
-
val bufferBytes = frameCount * BYTES_PER_FRAME
|
|
157
|
-
// A freshly allocated direct buffer is zero-filled, i.e. pure silence.
|
|
158
|
-
val silence = ByteBuffer.allocateDirect(bufferBytes)
|
|
159
|
-
|
|
160
|
-
val player = AudioTrack.Builder()
|
|
161
|
-
.setAudioAttributes(
|
|
162
|
-
AudioAttributes.Builder()
|
|
163
|
-
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
|
|
164
|
-
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
|
|
165
|
-
.build(),
|
|
166
|
-
)
|
|
167
|
-
.setAudioFormat(
|
|
168
|
-
AudioFormat.Builder()
|
|
169
|
-
.setEncoding(ENCODING)
|
|
170
|
-
.setSampleRate(sampleRate)
|
|
171
|
-
.setChannelMask(AudioFormat.CHANNEL_OUT_MONO)
|
|
172
|
-
.build(),
|
|
173
|
-
)
|
|
174
|
-
.setBufferSizeInBytes(bufferBytes)
|
|
175
|
-
.setTransferMode(AudioTrack.MODE_STATIC)
|
|
176
|
-
.setSessionId(AudioManager.AUDIO_SESSION_ID_GENERATE)
|
|
177
|
-
.build()
|
|
178
|
-
|
|
179
|
-
val written = player.write(silence, silence.remaining(), AudioTrack.WRITE_BLOCKING)
|
|
180
|
-
val loopResult = player.setLoopPoints(0, frameCount - 1, -1)
|
|
181
|
-
val ready = player.state == AudioTrack.STATE_INITIALIZED &&
|
|
182
|
-
written >= 0 &&
|
|
183
|
-
loopResult == AudioTrack.SUCCESS
|
|
184
|
-
if (ready) {
|
|
185
|
-
player
|
|
186
|
-
} else {
|
|
187
|
-
Log.w(
|
|
188
|
-
TAG,
|
|
189
|
-
"Silent keep-alive track not usable " +
|
|
190
|
-
"(state=${player.state}, written=$written, loop=$loopResult); discarding.",
|
|
191
|
-
)
|
|
192
|
-
player.release()
|
|
193
|
-
null
|
|
194
|
-
}
|
|
195
|
-
} catch (e: Exception) {
|
|
196
|
-
Log.w(TAG, "Could not create silent keep-alive track.", e)
|
|
197
|
-
null
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
private fun startModePoller() {
|
|
202
|
-
if (modePoller != null) return
|
|
203
|
-
modePoller = Executors.newSingleThreadScheduledExecutor().also { poller ->
|
|
204
|
-
poller.scheduleWithFixedDelay(
|
|
205
|
-
::reapplyModeIfReset,
|
|
206
|
-
MODE_POLL_INTERVAL_MS,
|
|
207
|
-
MODE_POLL_INTERVAL_MS,
|
|
208
|
-
TimeUnit.MILLISECONDS,
|
|
209
|
-
)
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
private fun reapplyModeIfReset() {
|
|
214
|
-
// Read/write the mode on the shared audio thread so it can't race routing changes.
|
|
215
|
-
AudioDeviceManager.runInAudioThread {
|
|
216
|
-
if (!live) return@runInAudioThread
|
|
217
|
-
val audioManager = context.getSystemService(AUDIO_SERVICE) as AudioManager
|
|
218
|
-
if (audioManager.mode != AudioManager.MODE_IN_COMMUNICATION) {
|
|
219
|
-
Log.d(TAG, "Re-applying MODE_IN_COMMUNICATION after a platform reset.")
|
|
220
|
-
audioManager.mode = AudioManager.MODE_IN_COMMUNICATION
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
private fun stopModePoller() {
|
|
226
|
-
modePoller?.shutdownNow()
|
|
227
|
-
modePoller = null
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
private fun positiveOrDefault(value: Int?, default: Int): Int =
|
|
231
|
-
if (value != null && value > 0) value else default
|
|
232
|
-
|
|
233
|
-
companion object {
|
|
234
|
-
private const val TAG = StreamInCallManagerModule.TAG
|
|
235
|
-
private const val DEFAULT_SAMPLE_RATE = 16000
|
|
236
|
-
private const val ENCODING = AudioFormat.ENCODING_PCM_16BIT
|
|
237
|
-
|
|
238
|
-
// We always emit mono 16-bit PCM, so a frame is exactly 2 bytes.
|
|
239
|
-
private const val BYTES_PER_FRAME = 2
|
|
240
|
-
|
|
241
|
-
// Fallback poll cadence. Deliberately shorter than AOSP's ~6s reset window: the
|
|
242
|
-
// interval bounds only the worst-case wrong-routing gap (<= interval), while the
|
|
243
|
-
// real setMode/HAL transition rate stays governed by the OS re-arm, so polling
|
|
244
|
-
// faster only costs cheap reads and shortens the recovery latency.
|
|
245
|
-
private const val MODE_POLL_INTERVAL_MS = 2000L
|
|
246
|
-
}
|
|
247
|
-
}
|