@stream-io/video-react-native-sdk 1.21.2 → 1.22.1-alpha.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.
- package/android/gradle.properties +3 -3
- package/android/src/main/java/com/streamvideo/reactnative/StreamVideoReactNativeModule.kt +10 -0
- package/android/src/main/java/com/streamvideo/reactnative/StreamVideoReactNativePackage.kt +2 -1
- package/android/src/main/java/com/streamvideo/reactnative/audio/AudioDeviceManager.kt +592 -0
- package/android/src/main/java/com/streamvideo/reactnative/audio/BluetoothManager.kt +755 -0
- package/android/src/main/java/com/streamvideo/reactnative/audio/utils/AudioDeviceEndpointUtils.kt +192 -0
- package/android/src/main/java/com/streamvideo/reactnative/audio/utils/AudioFocusUtil.kt +62 -0
- package/android/src/main/java/com/streamvideo/reactnative/audio/utils/AudioManagerUtil.kt +159 -0
- package/android/src/main/java/com/streamvideo/reactnative/audio/utils/AudioSetupStoreUtil.kt +41 -0
- package/android/src/main/java/com/streamvideo/reactnative/audio/utils/WebRtcAudioUtils.kt +250 -0
- package/android/src/main/java/com/streamvideo/reactnative/callmanager/StreamInCallManagerModule.kt +191 -0
- package/android/src/main/java/com/streamvideo/reactnative/model/AudioDeviceEndpoint.kt +136 -0
- package/android/src/main/java/org/webrtc/audio/WebRtcAudioTrackHelper.kt +12 -0
- package/dist/commonjs/components/Call/CallContent/CallContent.js +13 -9
- package/dist/commonjs/components/Call/CallContent/CallContent.js.map +1 -1
- package/dist/commonjs/components/Call/CallContent/RTCViewPipIOS.js +9 -2
- package/dist/commonjs/components/Call/CallContent/RTCViewPipIOS.js.map +1 -1
- package/dist/commonjs/components/Call/CallContent/RTCViewPipNative.js +3 -0
- package/dist/commonjs/components/Call/CallContent/RTCViewPipNative.js.map +1 -1
- package/dist/commonjs/components/Livestream/HostLivestream/HostLivestream.js +10 -6
- package/dist/commonjs/components/Livestream/HostLivestream/HostLivestream.js.map +1 -1
- package/dist/commonjs/components/Livestream/LivestreamControls/ViewerLivestreamControls.js +8 -4
- package/dist/commonjs/components/Livestream/LivestreamControls/ViewerLivestreamControls.js.map +1 -1
- package/dist/commonjs/components/Livestream/LivestreamLayout/LivestreamLayout.js +26 -27
- package/dist/commonjs/components/Livestream/LivestreamLayout/LivestreamLayout.js.map +1 -1
- package/dist/commonjs/components/Livestream/ViewerLivestream/ViewerLivestream.js +10 -6
- package/dist/commonjs/components/Livestream/ViewerLivestream/ViewerLivestream.js.map +1 -1
- package/dist/commonjs/hooks/useIsInPiPMode.js +3 -3
- package/dist/commonjs/hooks/useIsInPiPMode.js.map +1 -1
- package/dist/commonjs/hooks/usePermissionNotification.js +5 -5
- package/dist/commonjs/hooks/usePermissionNotification.js.map +1 -1
- package/dist/commonjs/index.js +12 -0
- package/dist/commonjs/index.js.map +1 -1
- package/dist/commonjs/modules/call-manager/CallManager.js +113 -0
- package/dist/commonjs/modules/call-manager/CallManager.js.map +1 -0
- package/dist/commonjs/modules/call-manager/PrevLibDetection.js +18 -0
- package/dist/commonjs/modules/call-manager/PrevLibDetection.js.map +1 -0
- package/dist/commonjs/modules/call-manager/index.js +24 -0
- package/dist/commonjs/modules/call-manager/index.js.map +1 -0
- package/dist/commonjs/modules/call-manager/native-module.d.js +4 -0
- package/dist/commonjs/modules/call-manager/native-module.d.js.map +1 -0
- package/dist/commonjs/modules/call-manager/types.js +2 -0
- package/dist/commonjs/modules/call-manager/types.js.map +1 -0
- package/dist/commonjs/providers/StreamCall/AppStateListener.js +5 -5
- package/dist/commonjs/providers/StreamCall/AppStateListener.js.map +1 -1
- package/dist/commonjs/theme/theme.js.map +1 -1
- package/dist/commonjs/utils/internal/rxSubjects.js +2 -2
- package/dist/commonjs/utils/internal/rxSubjects.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/commonjs/version.js.map +1 -1
- package/dist/module/components/Call/CallContent/CallContent.js +14 -9
- package/dist/module/components/Call/CallContent/CallContent.js.map +1 -1
- package/dist/module/components/Call/CallContent/RTCViewPipIOS.js +9 -2
- package/dist/module/components/Call/CallContent/RTCViewPipIOS.js.map +1 -1
- package/dist/module/components/Call/CallContent/RTCViewPipNative.js +3 -0
- package/dist/module/components/Call/CallContent/RTCViewPipNative.js.map +1 -1
- package/dist/module/components/Livestream/HostLivestream/HostLivestream.js +10 -5
- package/dist/module/components/Livestream/HostLivestream/HostLivestream.js.map +1 -1
- package/dist/module/components/Livestream/LivestreamControls/ViewerLivestreamControls.js +9 -4
- package/dist/module/components/Livestream/LivestreamControls/ViewerLivestreamControls.js.map +1 -1
- package/dist/module/components/Livestream/LivestreamLayout/LivestreamLayout.js +26 -27
- package/dist/module/components/Livestream/LivestreamLayout/LivestreamLayout.js.map +1 -1
- package/dist/module/components/Livestream/ViewerLivestream/ViewerLivestream.js +10 -5
- package/dist/module/components/Livestream/ViewerLivestream/ViewerLivestream.js.map +1 -1
- package/dist/module/hooks/useIsInPiPMode.js +4 -4
- package/dist/module/hooks/useIsInPiPMode.js.map +1 -1
- package/dist/module/hooks/usePermissionNotification.js +7 -6
- package/dist/module/hooks/usePermissionNotification.js.map +1 -1
- package/dist/module/icons/Back.js +1 -1
- package/dist/module/icons/Back.js.map +1 -1
- package/dist/module/icons/CameraSwitch.js +1 -1
- package/dist/module/icons/CameraSwitch.js.map +1 -1
- package/dist/module/icons/Mic.js +1 -1
- package/dist/module/icons/Mic.js.map +1 -1
- package/dist/module/icons/MicOff.js +1 -1
- package/dist/module/icons/MicOff.js.map +1 -1
- package/dist/module/icons/Phone.js +1 -1
- package/dist/module/icons/Phone.js.map +1 -1
- package/dist/module/icons/PinVertical.js +1 -1
- package/dist/module/icons/PinVertical.js.map +1 -1
- package/dist/module/icons/Reaction.js +1 -1
- package/dist/module/icons/Reaction.js.map +1 -1
- package/dist/module/icons/Spotlight.js +1 -1
- package/dist/module/icons/Spotlight.js.map +1 -1
- package/dist/module/icons/Video.js +1 -1
- package/dist/module/icons/Video.js.map +1 -1
- package/dist/module/icons/VideoSlash.js +1 -1
- package/dist/module/icons/VideoSlash.js.map +1 -1
- package/dist/module/index.js +1 -0
- package/dist/module/index.js.map +1 -1
- package/dist/module/modules/call-manager/CallManager.js +106 -0
- package/dist/module/modules/call-manager/CallManager.js.map +1 -0
- package/dist/module/modules/call-manager/PrevLibDetection.js +12 -0
- package/dist/module/modules/call-manager/PrevLibDetection.js.map +1 -0
- package/dist/module/modules/call-manager/index.js +4 -0
- package/dist/module/modules/call-manager/index.js.map +1 -0
- package/dist/module/modules/call-manager/native-module.d.js +2 -0
- package/dist/module/modules/call-manager/native-module.d.js.map +1 -0
- package/dist/module/modules/call-manager/types.js +2 -0
- package/dist/module/modules/call-manager/types.js.map +1 -0
- package/dist/module/providers/StreamCall/AppStateListener.js +6 -6
- package/dist/module/providers/StreamCall/AppStateListener.js.map +1 -1
- package/dist/module/theme/theme.js.map +1 -1
- package/dist/module/utils/internal/rxSubjects.js +1 -1
- package/dist/module/utils/internal/rxSubjects.js.map +1 -1
- package/dist/module/version.js +1 -1
- package/dist/module/version.js.map +1 -1
- package/dist/typescript/components/Call/CallContent/CallContent.d.ts +3 -2
- package/dist/typescript/components/Call/CallContent/CallContent.d.ts.map +1 -1
- package/dist/typescript/components/Call/CallContent/RTCViewPipIOS.d.ts +5 -0
- package/dist/typescript/components/Call/CallContent/RTCViewPipIOS.d.ts.map +1 -1
- package/dist/typescript/components/Call/CallContent/RTCViewPipNative.d.ts +6 -0
- package/dist/typescript/components/Call/CallContent/RTCViewPipNative.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/HostLivestream/HostLivestream.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/LivestreamControls/ViewerLivestreamControls.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/LivestreamLayout/LivestreamLayout.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/ViewerLivestream/ViewerLivestream.d.ts.map +1 -1
- package/dist/typescript/hooks/usePermissionNotification.d.ts.map +1 -1
- package/dist/typescript/icons/Back.d.ts +1 -1
- package/dist/typescript/icons/Back.d.ts.map +1 -1
- package/dist/typescript/icons/BadNetwork.d.ts +1 -1
- package/dist/typescript/icons/BadNetwork.d.ts.map +1 -1
- package/dist/typescript/icons/CameraSwitch.d.ts +1 -1
- package/dist/typescript/icons/CameraSwitch.d.ts.map +1 -1
- package/dist/typescript/icons/LivestreamControls.d.ts +1 -1
- package/dist/typescript/icons/LivestreamControls.d.ts.map +1 -1
- package/dist/typescript/icons/Lock.d.ts +1 -1
- package/dist/typescript/icons/Lock.d.ts.map +1 -1
- package/dist/typescript/icons/Maximize.d.ts +1 -1
- package/dist/typescript/icons/Maximize.d.ts.map +1 -1
- package/dist/typescript/icons/Mic.d.ts +1 -1
- package/dist/typescript/icons/Mic.d.ts.map +1 -1
- package/dist/typescript/icons/MicOff.d.ts +1 -1
- package/dist/typescript/icons/MicOff.d.ts.map +1 -1
- package/dist/typescript/icons/Phone.d.ts +1 -1
- package/dist/typescript/icons/Phone.d.ts.map +1 -1
- package/dist/typescript/icons/PhoneDown.d.ts +1 -1
- package/dist/typescript/icons/PhoneDown.d.ts.map +1 -1
- package/dist/typescript/icons/PinVertical.d.ts +1 -1
- package/dist/typescript/icons/PinVertical.d.ts.map +1 -1
- package/dist/typescript/icons/Reaction.d.ts +1 -1
- package/dist/typescript/icons/Reaction.d.ts.map +1 -1
- package/dist/typescript/icons/ScreenShare.d.ts +1 -1
- package/dist/typescript/icons/ScreenShare.d.ts.map +1 -1
- package/dist/typescript/icons/ScreenShareIndicator.d.ts +1 -1
- package/dist/typescript/icons/ScreenShareIndicator.d.ts.map +1 -1
- package/dist/typescript/icons/Spotlight.d.ts +1 -1
- package/dist/typescript/icons/Spotlight.d.ts.map +1 -1
- package/dist/typescript/icons/StopScreenShare.d.ts +1 -1
- package/dist/typescript/icons/StopScreenShare.d.ts.map +1 -1
- package/dist/typescript/icons/Video.d.ts +1 -1
- package/dist/typescript/icons/Video.d.ts.map +1 -1
- package/dist/typescript/icons/VideoSlash.d.ts +1 -1
- package/dist/typescript/icons/VideoSlash.d.ts.map +1 -1
- package/dist/typescript/index.d.ts +1 -0
- package/dist/typescript/index.d.ts.map +1 -1
- package/dist/typescript/modules/call-manager/CallManager.d.ts +67 -0
- package/dist/typescript/modules/call-manager/CallManager.d.ts.map +1 -0
- package/dist/typescript/modules/call-manager/PrevLibDetection.d.ts +13 -0
- package/dist/typescript/modules/call-manager/PrevLibDetection.d.ts.map +1 -0
- package/dist/typescript/modules/call-manager/index.d.ts +4 -0
- package/dist/typescript/modules/call-manager/index.d.ts.map +1 -0
- package/dist/typescript/modules/call-manager/types.d.ts +15 -0
- package/dist/typescript/modules/call-manager/types.d.ts.map +1 -0
- package/dist/typescript/providers/StreamCall/AppStateListener.d.ts.map +1 -1
- package/dist/typescript/theme/theme.d.ts +1 -2
- package/dist/typescript/theme/theme.d.ts.map +1 -1
- package/dist/typescript/utils/internal/rxSubjects.d.ts +1 -1
- package/dist/typescript/utils/internal/rxSubjects.d.ts.map +1 -1
- package/dist/typescript/version.d.ts +1 -1
- package/dist/typescript/version.d.ts.map +1 -1
- package/ios/PictureInPicture/StreamPictureInPictureController.swift +5 -0
- package/ios/RTCViewPip.swift +15 -0
- package/ios/RTCViewPipManager.mm +1 -0
- package/ios/StreamInCallManager.m +26 -0
- package/ios/StreamInCallManager.swift +303 -0
- package/ios/StreamVideoReactNative-Bridging-Header.h +1 -0
- package/ios/StreamVideoReactNative.m +6 -5
- package/ios/StreamVideoReactNative.xcodeproj/project.xcworkspace/xcuserdata/santhoshvaiyapuri.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/StreamVideoReactNative.xcodeproj/xcuserdata/santhoshvaiyapuri.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
- package/package.json +33 -35
- package/src/components/Call/CallContent/CallContent.tsx +14 -10
- package/src/components/Call/CallContent/RTCViewPipIOS.tsx +17 -2
- package/src/components/Call/CallContent/RTCViewPipNative.tsx +8 -0
- package/src/components/Livestream/HostLivestream/HostLivestream.tsx +8 -3
- package/src/components/Livestream/LivestreamControls/ViewerLivestreamControls.tsx +11 -5
- package/src/components/Livestream/LivestreamLayout/LivestreamLayout.tsx +38 -29
- package/src/components/Livestream/ViewerLivestream/ViewerLivestream.tsx +8 -3
- package/src/hooks/useIsInPiPMode.tsx +4 -4
- package/src/hooks/usePermissionNotification.tsx +7 -12
- package/src/icons/Back.tsx +2 -2
- package/src/icons/BadNetwork.tsx +1 -1
- package/src/icons/CameraSwitch.tsx +2 -2
- package/src/icons/LivestreamControls.tsx +1 -1
- package/src/icons/Lock.tsx +1 -1
- package/src/icons/Maximize.tsx +1 -1
- package/src/icons/Mic.tsx +2 -2
- package/src/icons/MicOff.tsx +2 -2
- package/src/icons/Phone.tsx +2 -2
- package/src/icons/PhoneDown.tsx +1 -1
- package/src/icons/PinVertical.tsx +2 -2
- package/src/icons/Reaction.tsx +2 -2
- package/src/icons/ScreenShare.tsx +1 -1
- package/src/icons/ScreenShareIndicator.tsx +1 -1
- package/src/icons/Spotlight.tsx +2 -2
- package/src/icons/StopScreenShare.tsx +1 -1
- package/src/icons/Video.tsx +2 -2
- package/src/icons/VideoSlash.tsx +2 -2
- package/src/index.ts +1 -0
- package/src/modules/call-manager/CallManager.ts +116 -0
- package/src/modules/call-manager/PrevLibDetection.ts +27 -0
- package/src/modules/call-manager/index.ts +5 -0
- package/src/modules/call-manager/native-module.d.ts +80 -0
- package/src/modules/call-manager/types.ts +25 -0
- package/src/providers/StreamCall/AppStateListener.tsx +6 -9
- package/src/theme/theme.ts +2 -2
- package/src/utils/internal/rxSubjects.ts +1 -1
- package/src/version.ts +1 -1
- package/CHANGELOG.md +0 -2783
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
|
|
3
|
+
*
|
|
4
|
+
* Use of this source code is governed by a BSD-style license
|
|
5
|
+
* that can be found in the LICENSE file in the root of the source
|
|
6
|
+
* tree. An additional intellectual property rights grant can be found
|
|
7
|
+
* in the file PATENTS. All contributing project authors may
|
|
8
|
+
* be found in the AUTHORS file in the root of the source tree.
|
|
9
|
+
*/
|
|
10
|
+
package com.streamvideo.reactnative.audio.utils
|
|
11
|
+
|
|
12
|
+
import android.content.Context
|
|
13
|
+
import android.content.pm.PackageManager
|
|
14
|
+
import android.media.AudioDeviceInfo
|
|
15
|
+
import android.media.AudioFormat
|
|
16
|
+
import android.media.AudioManager
|
|
17
|
+
import android.media.MediaRecorder
|
|
18
|
+
import android.os.Build
|
|
19
|
+
import android.util.Log
|
|
20
|
+
import com.facebook.react.bridge.ReactContext
|
|
21
|
+
|
|
22
|
+
/** Utilities for implementations of `AudioDeviceModule`, mostly for logging. */
|
|
23
|
+
object WebRtcAudioUtils {
|
|
24
|
+
/** Helper method for building a string of thread information. */
|
|
25
|
+
fun threadInfo(): String {
|
|
26
|
+
val current = Thread.currentThread()
|
|
27
|
+
return "@[name=" + current.name + ", id=" + current.id + "]"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Returns true if we're running on emulator. */
|
|
31
|
+
fun runningOnEmulator(): Boolean {
|
|
32
|
+
// Hardware type of qemu1 is goldfish and qemu2 is ranchu.
|
|
33
|
+
return Build.HARDWARE == "goldfish" || Build.HARDWARE == "ranchu"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Information about the current build, taken from system properties. */
|
|
37
|
+
private fun logDeviceInfo(tag: String) {
|
|
38
|
+
Log.d(
|
|
39
|
+
tag,
|
|
40
|
+
(("Android SDK: " + Build.VERSION.SDK_INT)
|
|
41
|
+
+ (", Release: " + Build.VERSION.RELEASE)
|
|
42
|
+
+ (", Brand: " + Build.BRAND)
|
|
43
|
+
+ (", Device: " + Build.DEVICE)
|
|
44
|
+
+ (", Id: " + Build.ID)
|
|
45
|
+
+ (", Hardware: " + Build.HARDWARE)
|
|
46
|
+
+ (", Manufacturer: " + Build.MANUFACTURER)
|
|
47
|
+
+ (", Model: " + Build.MODEL)
|
|
48
|
+
+ (", Product: " + Build.PRODUCT))
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Logs information about the current audio state. The idea is to call this method when errors are
|
|
54
|
+
* detected to log under what conditions the error occurred. Hopefully it will provide clues to
|
|
55
|
+
* what might be the root cause.
|
|
56
|
+
*/
|
|
57
|
+
fun logAudioState(tag: String, reactContext: ReactContext) {
|
|
58
|
+
reactContext.currentActivity?.let {
|
|
59
|
+
Log.d(tag, "volumeControlStream: " + streamTypeToString(it.volumeControlStream))
|
|
60
|
+
}
|
|
61
|
+
val audioManager = reactContext.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
|
62
|
+
logDeviceInfo(tag)
|
|
63
|
+
logAudioStateBasic(tag, reactContext, audioManager)
|
|
64
|
+
logAudioStateVolume(tag, audioManager)
|
|
65
|
+
logAudioDeviceInfo(tag, audioManager)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Converts AudioDeviceInfo types to local string representation. */
|
|
69
|
+
private fun deviceTypeToString(type: Int): String {
|
|
70
|
+
return when (type) {
|
|
71
|
+
AudioDeviceInfo.TYPE_AUX_LINE -> "TYPE_AUX_LINE"
|
|
72
|
+
AudioDeviceInfo.TYPE_BLE_BROADCAST -> "TYPE_BLE_BROADCAST"
|
|
73
|
+
AudioDeviceInfo.TYPE_BLE_HEADSET -> "TYPE_BLE_HEADSET"
|
|
74
|
+
AudioDeviceInfo.TYPE_BLE_SPEAKER -> "TYPE_BLE_SPEAKER"
|
|
75
|
+
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP -> "TYPE_BLUETOOTH_A2DP"
|
|
76
|
+
AudioDeviceInfo.TYPE_BLUETOOTH_SCO -> "TYPE_BLUETOOTH_SCO"
|
|
77
|
+
AudioDeviceInfo.TYPE_BUILTIN_EARPIECE -> "TYPE_BUILTIN_EARPIECE"
|
|
78
|
+
AudioDeviceInfo.TYPE_BUILTIN_MIC -> "TYPE_BUILTIN_MIC"
|
|
79
|
+
AudioDeviceInfo.TYPE_BUILTIN_SPEAKER -> "TYPE_BUILTIN_SPEAKER"
|
|
80
|
+
AudioDeviceInfo.TYPE_BUILTIN_SPEAKER_SAFE -> "TYPE_BUILTIN_SPEAKER_SAFE"
|
|
81
|
+
AudioDeviceInfo.TYPE_BUS -> "TYPE_BUS"
|
|
82
|
+
AudioDeviceInfo.TYPE_DOCK -> "TYPE_DOCK"
|
|
83
|
+
AudioDeviceInfo.TYPE_DOCK_ANALOG -> "TYPE_DOCK_ANALOG"
|
|
84
|
+
AudioDeviceInfo.TYPE_FM -> "TYPE_FM"
|
|
85
|
+
AudioDeviceInfo.TYPE_FM_TUNER -> "TYPE_FM_TUNER"
|
|
86
|
+
AudioDeviceInfo.TYPE_HDMI -> "TYPE_HDMI"
|
|
87
|
+
AudioDeviceInfo.TYPE_HDMI_ARC -> "TYPE_HDMI_ARC"
|
|
88
|
+
AudioDeviceInfo.TYPE_HDMI_EARC -> "TYPE_HDMI_EARC"
|
|
89
|
+
AudioDeviceInfo.TYPE_HEARING_AID -> "TYPE_HEARING_AID"
|
|
90
|
+
AudioDeviceInfo.TYPE_IP -> "TYPE_IP"
|
|
91
|
+
AudioDeviceInfo.TYPE_LINE_ANALOG -> "TYPE_LINE_ANALOG"
|
|
92
|
+
AudioDeviceInfo.TYPE_LINE_DIGITAL -> "TYPE_LINE_DIGITAL"
|
|
93
|
+
AudioDeviceInfo.TYPE_REMOTE_SUBMIX -> "TYPE_REMOTE_SUBMIX"
|
|
94
|
+
AudioDeviceInfo.TYPE_TELEPHONY -> "TYPE_TELEPHONY"
|
|
95
|
+
AudioDeviceInfo.TYPE_TV_TUNER -> "TYPE_TV_TUNER"
|
|
96
|
+
AudioDeviceInfo.TYPE_UNKNOWN -> "TYPE_UNKNOWN"
|
|
97
|
+
AudioDeviceInfo.TYPE_USB_ACCESSORY -> "TYPE_USB_ACCESSORY"
|
|
98
|
+
AudioDeviceInfo.TYPE_USB_DEVICE -> "TYPE_USB_DEVICE"
|
|
99
|
+
AudioDeviceInfo.TYPE_USB_HEADSET -> "TYPE_USB_HEADSET"
|
|
100
|
+
AudioDeviceInfo.TYPE_WIRED_HEADPHONES -> "TYPE_WIRED_HEADPHONES"
|
|
101
|
+
AudioDeviceInfo.TYPE_WIRED_HEADSET -> "TYPE_WIRED_HEADSET"
|
|
102
|
+
else -> "TYPE_UNKNOWN($type)"
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
fun audioSourceToString(source: Int): String {
|
|
107
|
+
return when (source) {
|
|
108
|
+
MediaRecorder.AudioSource.DEFAULT -> "DEFAULT"
|
|
109
|
+
MediaRecorder.AudioSource.MIC -> "MIC"
|
|
110
|
+
MediaRecorder.AudioSource.VOICE_UPLINK -> "VOICE_UPLINK"
|
|
111
|
+
MediaRecorder.AudioSource.VOICE_DOWNLINK -> "VOICE_DOWNLINK"
|
|
112
|
+
MediaRecorder.AudioSource.VOICE_CALL -> "VOICE_CALL"
|
|
113
|
+
MediaRecorder.AudioSource.CAMCORDER -> "CAMCORDER"
|
|
114
|
+
MediaRecorder.AudioSource.VOICE_RECOGNITION -> "VOICE_RECOGNITION"
|
|
115
|
+
MediaRecorder.AudioSource.VOICE_COMMUNICATION -> "VOICE_COMMUNICATION"
|
|
116
|
+
MediaRecorder.AudioSource.UNPROCESSED -> "UNPROCESSED"
|
|
117
|
+
MediaRecorder.AudioSource.VOICE_PERFORMANCE -> "VOICE_PERFORMANCE"
|
|
118
|
+
else -> "INVALID"
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
fun channelMaskToString(mask: Int): String {
|
|
123
|
+
// For input or AudioRecord, the mask should be AudioFormat#CHANNEL_IN_MONO or
|
|
124
|
+
// AudioFormat#CHANNEL_IN_STEREO. AudioFormat#CHANNEL_IN_MONO is guaranteed to work on all
|
|
125
|
+
// devices.
|
|
126
|
+
return when (mask) {
|
|
127
|
+
AudioFormat.CHANNEL_IN_STEREO -> "IN_STEREO"
|
|
128
|
+
AudioFormat.CHANNEL_IN_MONO -> "IN_MONO"
|
|
129
|
+
else -> "INVALID"
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
fun audioEncodingToString(enc: Int): String {
|
|
134
|
+
return when (enc) {
|
|
135
|
+
AudioFormat.ENCODING_INVALID -> "INVALID"
|
|
136
|
+
AudioFormat.ENCODING_PCM_16BIT -> "PCM_16BIT"
|
|
137
|
+
AudioFormat.ENCODING_PCM_8BIT -> "PCM_8BIT"
|
|
138
|
+
AudioFormat.ENCODING_PCM_FLOAT -> "PCM_FLOAT"
|
|
139
|
+
AudioFormat.ENCODING_AC3 -> "AC3"
|
|
140
|
+
AudioFormat.ENCODING_E_AC3 -> "AC3"
|
|
141
|
+
AudioFormat.ENCODING_DTS -> "DTS"
|
|
142
|
+
AudioFormat.ENCODING_DTS_HD -> "DTS_HD"
|
|
143
|
+
AudioFormat.ENCODING_MP3 -> "MP3"
|
|
144
|
+
else -> "Invalid encoding: $enc"
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** Reports basic audio statistics. */
|
|
149
|
+
private fun logAudioStateBasic(tag: String, context: Context, audioManager: AudioManager) {
|
|
150
|
+
Log.d(
|
|
151
|
+
tag,
|
|
152
|
+
("Audio State: "
|
|
153
|
+
+ ("audio mode: " + modeToString(audioManager.mode))
|
|
154
|
+
+ (", has mic: " + hasMicrophone(context))
|
|
155
|
+
+ (", mic muted: " + audioManager.isMicrophoneMute)
|
|
156
|
+
+ (", music active: " + audioManager.isMusicActive)
|
|
157
|
+
+ (", speakerphone: " + audioManager.isSpeakerphoneOn)
|
|
158
|
+
+ (", BT SCO: " + audioManager.isBluetoothScoOn))
|
|
159
|
+
)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** Adds volume information for all possible stream types. */
|
|
163
|
+
private fun logAudioStateVolume(tag: String, audioManager: AudioManager) {
|
|
164
|
+
val streams = intArrayOf(
|
|
165
|
+
AudioManager.STREAM_VOICE_CALL,
|
|
166
|
+
AudioManager.STREAM_MUSIC,
|
|
167
|
+
AudioManager.STREAM_RING,
|
|
168
|
+
AudioManager.STREAM_ALARM,
|
|
169
|
+
AudioManager.STREAM_NOTIFICATION,
|
|
170
|
+
AudioManager.STREAM_SYSTEM
|
|
171
|
+
)
|
|
172
|
+
Log.d(tag, "Audio State: ")
|
|
173
|
+
// Some devices may not have volume controls and might use a fixed volume.
|
|
174
|
+
val fixedVolume = audioManager.isVolumeFixed
|
|
175
|
+
Log.d(tag, " fixed volume=$fixedVolume")
|
|
176
|
+
if (!fixedVolume) {
|
|
177
|
+
for (stream in streams) {
|
|
178
|
+
val info = StringBuilder()
|
|
179
|
+
info.append(" " + streamTypeToString(stream) + ": ")
|
|
180
|
+
info.append("volume=").append(audioManager.getStreamVolume(stream))
|
|
181
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
|
182
|
+
info.append(", min=").append(audioManager.getStreamMinVolume(stream))
|
|
183
|
+
}
|
|
184
|
+
info.append(", max=").append(audioManager.getStreamMaxVolume(stream))
|
|
185
|
+
info.append(", muted=").append(audioManager.isStreamMute(stream))
|
|
186
|
+
Log.d(tag, info.toString())
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
private fun logAudioDeviceInfo(tag: String, audioManager: AudioManager) {
|
|
192
|
+
val inputDevices = audioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)
|
|
193
|
+
val outputDevices = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS)
|
|
194
|
+
val devices = inputDevices + outputDevices
|
|
195
|
+
if (devices.isEmpty()) {
|
|
196
|
+
return
|
|
197
|
+
}
|
|
198
|
+
Log.d(tag, "Audio Devices: ")
|
|
199
|
+
for (device in devices) {
|
|
200
|
+
val info = StringBuilder()
|
|
201
|
+
info.append(" ").append(deviceTypeToString(device.type))
|
|
202
|
+
info.append(if (device.isSource) "(in): " else "(out): ")
|
|
203
|
+
// An empty array indicates that the device supports arbitrary channel counts.
|
|
204
|
+
if (device.channelCounts.size > 0) {
|
|
205
|
+
info.append("channels=").append(device.channelCounts.contentToString())
|
|
206
|
+
info.append(", ")
|
|
207
|
+
}
|
|
208
|
+
if (device.encodings.size > 0) {
|
|
209
|
+
// Examples: ENCODING_PCM_16BIT = 2, ENCODING_PCM_FLOAT = 4.
|
|
210
|
+
info.append("encodings=").append(device.encodings.contentToString())
|
|
211
|
+
info.append(", ")
|
|
212
|
+
}
|
|
213
|
+
if (device.sampleRates.size > 0) {
|
|
214
|
+
info.append("sample rates=").append(device.sampleRates.contentToString())
|
|
215
|
+
info.append(", ")
|
|
216
|
+
}
|
|
217
|
+
info.append("id=").append(device.id)
|
|
218
|
+
Log.d(tag, info.toString())
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** Converts media.AudioManager modes into local string representation. */
|
|
223
|
+
fun modeToString(mode: Int): String {
|
|
224
|
+
return when (mode) {
|
|
225
|
+
AudioManager.MODE_IN_CALL -> "MODE_IN_CALL"
|
|
226
|
+
AudioManager.MODE_IN_COMMUNICATION -> "MODE_IN_COMMUNICATION"
|
|
227
|
+
AudioManager.MODE_NORMAL -> "MODE_NORMAL"
|
|
228
|
+
AudioManager.MODE_RINGTONE -> "MODE_RINGTONE"
|
|
229
|
+
else -> "MODE_INVALID"
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
private fun streamTypeToString(stream: Int): String {
|
|
234
|
+
return when (stream) {
|
|
235
|
+
AudioManager.STREAM_VOICE_CALL -> "STREAM_VOICE_CALL"
|
|
236
|
+
AudioManager.STREAM_MUSIC -> "STREAM_MUSIC"
|
|
237
|
+
AudioManager.STREAM_RING -> "STREAM_RING"
|
|
238
|
+
AudioManager.STREAM_ALARM -> "STREAM_ALARM"
|
|
239
|
+
AudioManager.STREAM_NOTIFICATION -> "STREAM_NOTIFICATION"
|
|
240
|
+
AudioManager.STREAM_SYSTEM -> "STREAM_SYSTEM"
|
|
241
|
+
else -> "STREAM_INVALID"
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/** Returns true if the device can record audio via a microphone. */
|
|
246
|
+
private fun hasMicrophone(context: Context): Boolean {
|
|
247
|
+
return context.packageManager.hasSystemFeature(PackageManager.FEATURE_MICROPHONE)
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
}
|
package/android/src/main/java/com/streamvideo/reactnative/callmanager/StreamInCallManagerModule.kt
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
package com.streamvideo.reactnative.callmanager
|
|
2
|
+
|
|
3
|
+
import android.util.Log
|
|
4
|
+
import android.view.WindowManager
|
|
5
|
+
import com.facebook.react.bridge.LifecycleEventListener
|
|
6
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
7
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
8
|
+
import com.facebook.react.bridge.ReactMethod
|
|
9
|
+
import com.facebook.react.bridge.UiThreadUtil
|
|
10
|
+
import com.streamvideo.reactnative.audio.AudioDeviceManager
|
|
11
|
+
import com.streamvideo.reactnative.audio.utils.CallAudioRole
|
|
12
|
+
import com.streamvideo.reactnative.audio.utils.WebRtcAudioUtils
|
|
13
|
+
import com.streamvideo.reactnative.model.AudioDeviceEndpoint
|
|
14
|
+
import java.util.Locale
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class StreamInCallManagerModule(reactContext: ReactApplicationContext) :
|
|
18
|
+
ReactContextBaseJavaModule(reactContext), LifecycleEventListener {
|
|
19
|
+
|
|
20
|
+
private var audioManagerActivated = false
|
|
21
|
+
|
|
22
|
+
private val mAudioDeviceManager = AudioDeviceManager(reactContext)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
override fun getName(): String {
|
|
26
|
+
return TAG
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
init {
|
|
30
|
+
reactContext.addLifecycleEventListener(this)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// This method was removed upstream in react-native 0.74+, replaced with invalidate
|
|
34
|
+
// We will leave this stub here for older react-native versions compatibility
|
|
35
|
+
// ...but it will just delegate to the new invalidate method
|
|
36
|
+
@Deprecated("Deprecated in Java", ReplaceWith("invalidate()"))
|
|
37
|
+
@Suppress("removal")
|
|
38
|
+
override fun onCatalystInstanceDestroy() {
|
|
39
|
+
invalidate()
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
override fun invalidate() {
|
|
43
|
+
mAudioDeviceManager.close()
|
|
44
|
+
super.invalidate()
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@ReactMethod
|
|
48
|
+
fun setAudioRole(audioRole: String) {
|
|
49
|
+
AudioDeviceManager.runInAudioThread {
|
|
50
|
+
if (audioManagerActivated) {
|
|
51
|
+
Log.e(TAG, "setAudioRole(): AudioManager is already activated and so Audio Role cannot be changed, current audio role is ${mAudioDeviceManager.callAudioRole}")
|
|
52
|
+
return@runInAudioThread
|
|
53
|
+
}
|
|
54
|
+
val role = audioRole.lowercase(Locale.getDefault())
|
|
55
|
+
Log.d(TAG, "setAudioRole(): $audioRole $role")
|
|
56
|
+
if (role == "listener") {
|
|
57
|
+
mAudioDeviceManager.callAudioRole = CallAudioRole.Listener
|
|
58
|
+
} else {
|
|
59
|
+
mAudioDeviceManager.callAudioRole = CallAudioRole.Communicator
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@ReactMethod
|
|
65
|
+
fun setDefaultAudioDeviceEndpointType(endpointDeviceTypeName: String) {
|
|
66
|
+
AudioDeviceManager.runInAudioThread {
|
|
67
|
+
if (audioManagerActivated) {
|
|
68
|
+
Log.e(TAG, "setAudioRole(): AudioManager is already activated and so default audio device cannot be changed, current audio default device is ${mAudioDeviceManager.defaultAudioDevice}")
|
|
69
|
+
return@runInAudioThread
|
|
70
|
+
}
|
|
71
|
+
val endpointType = endpointDeviceTypeName.lowercase(Locale.getDefault())
|
|
72
|
+
Log.d(TAG, "runInAudioThread(): $endpointDeviceTypeName $endpointType")
|
|
73
|
+
if (endpointType == "earpiece") {
|
|
74
|
+
mAudioDeviceManager.defaultAudioDevice = AudioDeviceEndpoint.TYPE_EARPIECE
|
|
75
|
+
} else {
|
|
76
|
+
mAudioDeviceManager.defaultAudioDevice = AudioDeviceEndpoint.TYPE_SPEAKER
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@ReactMethod
|
|
82
|
+
fun start() {
|
|
83
|
+
AudioDeviceManager.runInAudioThread {
|
|
84
|
+
if (!audioManagerActivated) {
|
|
85
|
+
reactApplicationContext.currentActivity?.let {
|
|
86
|
+
Log.d(TAG, "start() mAudioDeviceManager")
|
|
87
|
+
mAudioDeviceManager.start(it)
|
|
88
|
+
setKeepScreenOn(true)
|
|
89
|
+
audioManagerActivated = true
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@ReactMethod
|
|
96
|
+
fun stop() {
|
|
97
|
+
AudioDeviceManager.runInAudioThread {
|
|
98
|
+
if (audioManagerActivated) {
|
|
99
|
+
Log.d(TAG, "stop() mAudioDeviceManager")
|
|
100
|
+
mAudioDeviceManager.stop()
|
|
101
|
+
setMicrophoneMute(false)
|
|
102
|
+
setKeepScreenOn(false)
|
|
103
|
+
audioManagerActivated = false
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private fun setKeepScreenOn(enable: Boolean) {
|
|
109
|
+
Log.d(TAG, "setKeepScreenOn() $enable")
|
|
110
|
+
UiThreadUtil.runOnUiThread {
|
|
111
|
+
reactApplicationContext.currentActivity?.let {
|
|
112
|
+
val window = it.window
|
|
113
|
+
if (enable) {
|
|
114
|
+
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
|
115
|
+
} else {
|
|
116
|
+
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@Suppress("unused")
|
|
123
|
+
@ReactMethod
|
|
124
|
+
fun setForceSpeakerphoneOn(enable: Boolean) {
|
|
125
|
+
if (mAudioDeviceManager.callAudioRole !== CallAudioRole.Communicator) {
|
|
126
|
+
Log.e(TAG, "setForceSpeakerphoneOn() is not supported when audio role is not Communicator")
|
|
127
|
+
return
|
|
128
|
+
}
|
|
129
|
+
mAudioDeviceManager.setSpeakerphoneOn(enable)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
@ReactMethod
|
|
133
|
+
fun setMicrophoneMute(enable: Boolean) {
|
|
134
|
+
mAudioDeviceManager.setMicrophoneMute(enable)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
@ReactMethod
|
|
138
|
+
fun logAudioState() {
|
|
139
|
+
WebRtcAudioUtils.logAudioState(
|
|
140
|
+
TAG,
|
|
141
|
+
reactApplicationContext,
|
|
142
|
+
)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
@Suppress("unused")
|
|
146
|
+
@ReactMethod
|
|
147
|
+
fun chooseAudioDeviceEndpoint(endpointDeviceName: String) {
|
|
148
|
+
if (mAudioDeviceManager.callAudioRole !== CallAudioRole.Communicator) {
|
|
149
|
+
Log.e(TAG, "chooseAudioDeviceEndpoint() is not supported when audio role is not Communicator")
|
|
150
|
+
return
|
|
151
|
+
}
|
|
152
|
+
mAudioDeviceManager.switchDeviceFromDeviceName(
|
|
153
|
+
endpointDeviceName
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
@ReactMethod
|
|
158
|
+
fun muteAudioOutput() {
|
|
159
|
+
mAudioDeviceManager.muteAudioOutput()
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
@ReactMethod
|
|
163
|
+
fun unmuteAudioOutput() {
|
|
164
|
+
mAudioDeviceManager.unmuteAudioOutput()
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
override fun onHostResume() {
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
override fun onHostPause() {
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
override fun onHostDestroy() {
|
|
174
|
+
stop()
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
@ReactMethod
|
|
178
|
+
fun addListener(eventName: String?) {
|
|
179
|
+
// Keep: Required for RN built in Event Emitter Calls.
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
@ReactMethod
|
|
183
|
+
fun removeListeners(count: Int?) {
|
|
184
|
+
// Keep: Required for RN built in Event Emitter Calls.
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
companion object {
|
|
188
|
+
const val TAG = "StreamInCallManager"
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 The Android Open Source Project
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
package com.streamvideo.reactnative.model
|
|
18
|
+
|
|
19
|
+
import android.media.AudioDeviceInfo
|
|
20
|
+
import androidx.annotation.IntDef
|
|
21
|
+
import androidx.annotation.RestrictTo
|
|
22
|
+
import com.streamvideo.reactnative.audio.utils.AudioDeviceEndpointUtils
|
|
23
|
+
import java.util.Objects
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Represents a single audio device endpoint.
|
|
27
|
+
* @param name The name of the device. Bluetooth devices have their proper names, everything else their endpoint name. See [AudioDeviceEndpointUtils.remapAudioDeviceNameToEndpointDeviceName]
|
|
28
|
+
* @param type The type of endpoint.
|
|
29
|
+
* @param deviceInfo The [AudioDeviceInfo] associated with the endpoint.
|
|
30
|
+
*/
|
|
31
|
+
public class AudioDeviceEndpoint(
|
|
32
|
+
public val name: String,
|
|
33
|
+
@EndpointType public val type: Int,
|
|
34
|
+
public val deviceInfo: AudioDeviceInfo,
|
|
35
|
+
) : Comparable<AudioDeviceEndpoint> {
|
|
36
|
+
|
|
37
|
+
val deviceId = deviceInfo.id
|
|
38
|
+
|
|
39
|
+
override fun toString(): String {
|
|
40
|
+
return "CallEndpoint(" +
|
|
41
|
+
"name=[$name]," +
|
|
42
|
+
"type=[${
|
|
43
|
+
AudioDeviceEndpointUtils.endpointTypeToString(type)}]," +
|
|
44
|
+
"deviceId=[${deviceId}])"
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Compares this [AudioDeviceEndpoint] to the other [AudioDeviceEndpoint] for order. Returns a
|
|
49
|
+
* positive number if this type rank is greater than the other value. Returns a negative number
|
|
50
|
+
* if this type rank is less than the other value. Sort the CallEndpoint by type. Ranking them
|
|
51
|
+
* by:
|
|
52
|
+
* 1. TYPE_WIRED_HEADSET
|
|
53
|
+
* 2. TYPE_BLUETOOTH
|
|
54
|
+
* 3. TYPE_SPEAKER
|
|
55
|
+
* 4. TYPE_EARPIECE
|
|
56
|
+
* 5. TYPE_UNKNOWN If two endpoints have the same type, the name is compared to determine the
|
|
57
|
+
* value.
|
|
58
|
+
*/
|
|
59
|
+
override fun compareTo(other: AudioDeviceEndpoint): Int {
|
|
60
|
+
// sort by type
|
|
61
|
+
val res = this.getTypeRank().compareTo(other.getTypeRank())
|
|
62
|
+
if (res != 0) {
|
|
63
|
+
return res
|
|
64
|
+
}
|
|
65
|
+
// break ties using alphabetic order
|
|
66
|
+
return this.name.toString().compareTo(other.name.toString())
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
override fun equals(other: Any?): Boolean {
|
|
70
|
+
return other is AudioDeviceEndpoint &&
|
|
71
|
+
name == other.name &&
|
|
72
|
+
type == other.type && deviceId == other.deviceId
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
override fun hashCode(): Int {
|
|
76
|
+
return Objects.hash(name, type, deviceId)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public companion object {
|
|
80
|
+
@RestrictTo(RestrictTo.Scope.LIBRARY)
|
|
81
|
+
@Retention(AnnotationRetention.SOURCE)
|
|
82
|
+
@IntDef(
|
|
83
|
+
TYPE_UNKNOWN,
|
|
84
|
+
TYPE_EARPIECE,
|
|
85
|
+
TYPE_BLUETOOTH,
|
|
86
|
+
TYPE_WIRED_HEADSET,
|
|
87
|
+
TYPE_SPEAKER,
|
|
88
|
+
)
|
|
89
|
+
@Target(AnnotationTarget.TYPE, AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER)
|
|
90
|
+
public annotation class EndpointType
|
|
91
|
+
|
|
92
|
+
/** Indicates that the type of endpoint through which call media flows is unknown type. */
|
|
93
|
+
public const val TYPE_UNKNOWN: Int = -1
|
|
94
|
+
|
|
95
|
+
/** Indicates that the type of endpoint through which call media flows is an earpiece. */
|
|
96
|
+
public const val TYPE_EARPIECE: Int = 1
|
|
97
|
+
|
|
98
|
+
/** Indicates that the type of endpoint through which call media flows is a Bluetooth. */
|
|
99
|
+
public const val TYPE_BLUETOOTH: Int = 2
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Indicates that the type of endpoint through which call media flows is a wired headset.
|
|
103
|
+
*/
|
|
104
|
+
public const val TYPE_WIRED_HEADSET: Int = 3
|
|
105
|
+
|
|
106
|
+
/** Indicates that the type of endpoint through which call media flows is a speakerphone. */
|
|
107
|
+
public const val TYPE_SPEAKER: Int = 4
|
|
108
|
+
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
internal fun isBluetoothType(): Boolean {
|
|
112
|
+
return type == TYPE_BLUETOOTH
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
internal fun isSpeakerType(): Boolean {
|
|
116
|
+
return type == TYPE_SPEAKER
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
internal fun isWiredHeadsetType(): Boolean {
|
|
120
|
+
return type == TYPE_WIRED_HEADSET
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
internal fun isEarpieceType(): Boolean {
|
|
124
|
+
return type == TYPE_EARPIECE
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
private fun getTypeRank(): Int {
|
|
128
|
+
return when (this.type) {
|
|
129
|
+
TYPE_WIRED_HEADSET -> return 0
|
|
130
|
+
TYPE_BLUETOOTH -> return 1
|
|
131
|
+
TYPE_SPEAKER -> return 2
|
|
132
|
+
TYPE_EARPIECE -> return 3
|
|
133
|
+
else -> 4
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
package org.webrtc.audio
|
|
2
|
+
|
|
3
|
+
import android.media.AudioAttributes
|
|
4
|
+
|
|
5
|
+
object WebRtcAudioTrackHelper {
|
|
6
|
+
fun setAudioOutputAttributes(
|
|
7
|
+
adm: JavaAudioDeviceModule,
|
|
8
|
+
audioAttributes: AudioAttributes,
|
|
9
|
+
) {
|
|
10
|
+
adm.audioOutput.audioAttributes = audioAttributes
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.CallContent = void 0;
|
|
7
7
|
var _react = _interopRequireWildcard(require("react"));
|
|
8
8
|
var _reactNative = require("react-native");
|
|
9
|
-
var _reactNativeIncallManager = _interopRequireDefault(require("react-native-incall-manager"));
|
|
10
9
|
var _CallLayout = require("../CallLayout");
|
|
11
10
|
var _CallControls = require("../CallControls");
|
|
12
11
|
var _videoReactBindings = require("@stream-io/video-react-bindings");
|
|
@@ -18,7 +17,7 @@ var _contexts = require("../../../contexts");
|
|
|
18
17
|
var _hooks2 = require("../../../hooks");
|
|
19
18
|
var _ScreenShareOverlay = require("../../utility/ScreenShareOverlay");
|
|
20
19
|
var _RTCViewPipIOS = require("./RTCViewPipIOS");
|
|
21
|
-
|
|
20
|
+
var _PrevLibDetection = require("../../../modules/call-manager/PrevLibDetection");
|
|
22
21
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
23
22
|
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
24
23
|
const CallContent = ({
|
|
@@ -36,9 +35,9 @@ const CallContent = ({
|
|
|
36
35
|
layout = 'grid',
|
|
37
36
|
landscape = false,
|
|
38
37
|
supportedReactions,
|
|
38
|
+
initialInCallManagerAudioMode = 'video',
|
|
39
39
|
iOSPiPIncludeLocalParticipantVideo,
|
|
40
|
-
disablePictureInPicture
|
|
41
|
-
initialInCallManagerAudioMode = 'video'
|
|
40
|
+
disablePictureInPicture
|
|
42
41
|
}) => {
|
|
43
42
|
const [showRemoteParticipantInFloatingView, setShowRemoteParticipantInFloatingView] = (0, _react.useState)(false);
|
|
44
43
|
const styles = useStyles();
|
|
@@ -54,7 +53,6 @@ const CallContent = ({
|
|
|
54
53
|
useLocalParticipant
|
|
55
54
|
} = (0, _videoReactBindings.useCallStateHooks)();
|
|
56
55
|
(0, _hooks2.useAutoEnterPiPEffect)(disablePictureInPicture);
|
|
57
|
-
const incallManagerModeRef = (0, _react.useRef)(initialInCallManagerAudioMode);
|
|
58
56
|
const _remoteParticipants = useRemoteParticipants();
|
|
59
57
|
const remoteParticipants = (0, _hooks.useDebouncedValue)(_remoteParticipants, 300); // we debounce the remote participants to avoid unnecessary rerenders that happen when participant tracks are all subscribed simultaneously
|
|
60
58
|
const localParticipant = useLocalParticipant();
|
|
@@ -85,11 +83,17 @@ const CallContent = ({
|
|
|
85
83
|
/**
|
|
86
84
|
* This hook is used to handle IncallManager specs of the application.
|
|
87
85
|
*/
|
|
86
|
+
const incallManagerModeRef = (0, _react.useRef)(initialInCallManagerAudioMode);
|
|
88
87
|
(0, _react.useEffect)(() => {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
88
|
+
const prevInCallManager = (0, _PrevLibDetection.getRNInCallManagerLibNoThrow)();
|
|
89
|
+
if (prevInCallManager) {
|
|
90
|
+
prevInCallManager.start({
|
|
91
|
+
media: incallManagerModeRef.current
|
|
92
|
+
});
|
|
93
|
+
return () => {
|
|
94
|
+
prevInCallManager.stop();
|
|
95
|
+
};
|
|
96
|
+
}
|
|
93
97
|
}, []);
|
|
94
98
|
const handleFloatingViewParticipantSwitch = () => {
|
|
95
99
|
if (remoteParticipants.length !== 1) {
|