@cometchat/calls-sdk-react-native 4.4.2-beta.1 → 5.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.
Files changed (91) hide show
  1. package/README.md +85 -19
  2. package/android/.gradle/8.9/checksums/checksums.lock +0 -0
  3. package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
  4. package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
  5. package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
  6. package/android/.gradle/8.9/gc.properties +0 -0
  7. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  8. package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
  9. package/android/.gradle/vcs-1/gc.properties +0 -0
  10. package/android/build.gradle +13 -12
  11. package/android/src/main/AndroidManifest.xml +15 -6
  12. package/android/src/main/java/com/callingv5/AudioDeviceHandlerConnectionService.java +185 -0
  13. package/android/src/main/java/com/callingv5/AudioDeviceHandlerGeneric.java +254 -0
  14. package/android/src/main/java/com/{CometChatCalls → callingv5}/AudioModeModule.java +93 -56
  15. package/android/src/main/java/com/callingv5/ConnectionService.java +451 -0
  16. package/android/src/main/java/com/callingv5/KeepAwakeModule.java +53 -0
  17. package/android/src/main/java/com/callingv5/MyAppPackage.java +35 -0
  18. package/android/src/main/java/com/callingv5/RNConnectionService.java +244 -0
  19. package/android/src/main/java/com/callingv5/ToastModule.java +29 -0
  20. package/android/src/main/java/com/callingv5/utils/CometChatLogger.java +88 -0
  21. package/dist/index.d.mts +3940 -0
  22. package/dist/index.d.ts +3940 -9
  23. package/dist/index.js +10990 -132
  24. package/dist/index.js.map +1 -0
  25. package/dist/index.mjs +10959 -0
  26. package/dist/index.mjs.map +1 -0
  27. package/dist/polyfills/RTCPeerConnection.js +19 -0
  28. package/dist/polyfills/Storage.js +192 -0
  29. package/dist/polyfills/browser.js +337 -0
  30. package/dist/polyfills/index.js +1 -0
  31. package/dist/polyfills/ipv6utils.js +197 -0
  32. package/dist/polyfills/webrtc.js +11 -0
  33. package/package.json +18 -111
  34. package/LICENSE.md +0 -3
  35. package/android/src/main/java/com/CometChatCalls/AudioDeviceHandlerGeneric.java +0 -213
  36. package/android/src/main/java/com/CometChatCalls/AudioDeviceHandlerLegacy.java +0 -213
  37. package/android/src/main/java/com/CometChatCalls/BluetoothHeadsetMonitor.java +0 -187
  38. package/android/src/main/java/com/CometChatCalls/CallNotificationService.java +0 -93
  39. package/android/src/main/java/com/CometChatCalls/CallNotificationServiceModule.java +0 -48
  40. package/android/src/main/java/com/CometChatCalls/CometChatCallsPackage.java +0 -56
  41. package/android/src/main/java/com/CometChatCalls/CometChatCommonModule.java +0 -48
  42. package/android/src/main/java/com/CometChatCalls/PictureInPictureModule.java +0 -133
  43. package/android/src/main/res/drawable-mdpi/callingcomponent_icons_headphones_pluged.png +0 -0
  44. package/cometchat-calls-sdk-react-native.podspec +0 -21
  45. package/dist/CometChatErrorConstants.d.ts +0 -124
  46. package/dist/Constants.d.ts +0 -724
  47. package/dist/Helper copy.d.ts +0 -1
  48. package/dist/Helper.d.ts +0 -7
  49. package/dist/api/APIHandler.d.ts +0 -42
  50. package/dist/api/endpoints.d.ts +0 -7
  51. package/dist/api/helper.d.ts +0 -69
  52. package/dist/api/index.d.ts +0 -2
  53. package/dist/constants/CallConstants.d.ts +0 -136
  54. package/dist/constants/index.d.ts +0 -1
  55. package/dist/defaultCallsettings.d.ts +0 -2
  56. package/dist/models/CallAppSettings.d.ts +0 -42
  57. package/dist/models/CallGroup.d.ts +0 -14
  58. package/dist/models/CallLog.d.ts +0 -276
  59. package/dist/models/CallLogFilterParams.d.ts +0 -97
  60. package/dist/models/CallSettings.d.ts +0 -330
  61. package/dist/models/CallUser.d.ts +0 -14
  62. package/dist/models/CometChatCallLogs.d.ts +0 -193
  63. package/dist/models/CometChatCalls.d.ts +0 -110
  64. package/dist/models/CometChatCallsComponent.d.ts +0 -13
  65. package/dist/models/CometChatCallsComponentCore.d.ts +0 -18
  66. package/dist/models/CometChatCallsException.d.ts +0 -7
  67. package/dist/models/CometChatPresenterComponent.d.ts +0 -13
  68. package/dist/models/ErrorModel.d.ts +0 -11
  69. package/dist/models/Listner.d.ts +0 -69
  70. package/dist/models/ListnerHandler.d.ts +0 -10
  71. package/dist/models/MessageComponent.d.ts +0 -7
  72. package/dist/models/Participant.d.ts +0 -184
  73. package/dist/models/PresenterSettings.d.ts +0 -208
  74. package/dist/models/RTCUser.d.ts +0 -18
  75. package/dist/models/Recording.d.ts +0 -86
  76. package/dist/models/index.d.ts +0 -9
  77. package/dist/types/ICallAppSettings.d.ts +0 -6
  78. package/dist/types/ICallSettings.d.ts +0 -61
  79. package/dist/types/RTCUser.d.ts +0 -6
  80. package/dist/types/callEvents.d.ts +0 -54
  81. package/dist/types/common.d.ts +0 -18
  82. package/dist/types/index.d.ts +0 -2
  83. package/ios/AudioMode.h +0 -11
  84. package/ios/AudioMode.m +0 -418
  85. package/ios/CometChatCommonModule.h +0 -6
  86. package/ios/CometChatCommonModule.m +0 -29
  87. package/ios/JitsiAudioSession+Private.h +0 -25
  88. package/ios/JitsiAudioSession.h +0 -17
  89. package/ios/JitsiAudioSession.m +0 -34
  90. package/ios/LogUtils.h +0 -23
  91. package/ios/react-native-calls2.xcodeproj/project.pbxproj +0 -269
package/README.md CHANGED
@@ -1,31 +1,97 @@
1
- <p align="center">
2
- <img alt="CometChat" src="https://assets.cometchat.io/website/images/logos/banner.png">
3
- </p>
1
+ This is a new [**React Native**](https://reactnative.dev) project, bootstrapped using [`@react-native-community/cli`](https://github.com/react-native-community/cli).
4
2
 
3
+ # Getting Started
5
4
 
6
- # CometChat React Native Calls SDK
5
+ > **Note**: Make sure you have completed the [Set Up Your Environment](https://reactnative.dev/docs/set-up-your-environment) guide before proceeding.
7
6
 
8
- CometChat enables you to add voice, video & text chat for your website & app.
9
- ___
7
+ ## Step 1: Start Metro
10
8
 
11
- ## Prerequisites :star:
9
+ First, you will need to run **Metro**, the JavaScript build tool for React Native.
12
10
 
13
- Before starting, ensure you have set up your React Native development environment correctly by following the guide at https://reactnative.dev/docs/environment-setup
11
+ To start the Metro dev server, run the following command from the root of your React Native project:
14
12
 
15
- ___
13
+ ```sh
14
+ # Using npm
15
+ npm start
16
16
 
17
- ## Setting up React Native Calls SDK
18
- Follow the official React Native Calls SDK setup guide in our documentation:
19
- https://www.cometchat.com/docs/sdk/react-native/overview
17
+ # OR using Yarn
18
+ yarn start
19
+ ```
20
20
 
21
- ---
21
+ ## Step 2: Build and run your app
22
22
 
23
- ## Checkout our sample apps
24
- Explore our React Native sample apps & UI Kit examples here:
25
- https://github.com/cometchat/cometchat-uikit-react-native/tree/v5/examples
23
+ With Metro running, open a new terminal window/pane from the root of your React Native project, and use one of the following commands to build and run your Android or iOS app:
26
24
 
27
- ---
25
+ ### Android
28
26
 
27
+ ```sh
28
+ # Using npm
29
+ npm run android
29
30
 
30
- ## Help and Support
31
- For issues running the project or integrating with our UI Kits, consult our [documentation](https://www.cometchat.com/docs) or create a [support ticket](https://help.cometchat.com/hc/en-us) or seek real-time support via the [CometChat Dashboard](https://app.cometchat.com/).
31
+ # OR using Yarn
32
+ yarn android
33
+ ```
34
+
35
+ ### iOS
36
+
37
+ For iOS, remember to install CocoaPods dependencies (this only needs to be run on first clone or after updating native deps).
38
+
39
+ The first time you create a new project, run the Ruby bundler to install CocoaPods itself:
40
+
41
+ ```sh
42
+ bundle install
43
+ ```
44
+
45
+ Then, and every time you update your native dependencies, run:
46
+
47
+ ```sh
48
+ bundle exec pod install
49
+ ```
50
+
51
+ For more information, please visit [CocoaPods Getting Started guide](https://guides.cocoapods.org/using/getting-started.html).
52
+
53
+ ```sh
54
+ # Using npm
55
+ npm run ios
56
+
57
+ # OR using Yarn
58
+ yarn ios
59
+ ```
60
+
61
+ If everything is set up correctly, you should see your new app running in the Android Emulator, iOS Simulator, or your connected device.
62
+
63
+ This is one way to run your app — you can also build it directly from Android Studio or Xcode.
64
+
65
+ ## Step 3: Modify your app
66
+
67
+ Now that you have successfully run the app, let's make changes!
68
+
69
+ Open `App.tsx` in your text editor of choice and make some changes. When you save, your app will automatically update and reflect these changes — this is powered by [Fast Refresh](https://reactnative.dev/docs/fast-refresh).
70
+
71
+ When you want to forcefully reload, for example to reset the state of your app, you can perform a full reload:
72
+
73
+ - **Android**: Press the <kbd>R</kbd> key twice or select **"Reload"** from the **Dev Menu**, accessed via <kbd>Ctrl</kbd> + <kbd>M</kbd> (Windows/Linux) or <kbd>Cmd ⌘</kbd> + <kbd>M</kbd> (macOS).
74
+ - **iOS**: Press <kbd>R</kbd> in iOS Simulator.
75
+
76
+ ## Congratulations! :tada:
77
+
78
+ You've successfully run and modified your React Native App. :partying_face:
79
+
80
+ ### Now what?
81
+
82
+ - If you want to add this new React Native code to an existing application, check out the [Integration guide](https://reactnative.dev/docs/integration-with-existing-apps).
83
+ - If you're curious to learn more about React Native, check out the [docs](https://reactnative.dev/docs/getting-started).
84
+
85
+ # Troubleshooting
86
+
87
+ If you're having issues getting the above steps to work, see the [Troubleshooting](https://reactnative.dev/docs/troubleshooting) page.
88
+
89
+ # Learn More
90
+
91
+ To learn more about React Native, take a look at the following resources:
92
+
93
+ - [React Native Website](https://reactnative.dev) - learn more about React Native.
94
+ - [Getting Started](https://reactnative.dev/docs/environment-setup) - an **overview** of React Native and how setup your environment.
95
+ - [Learn the Basics](https://reactnative.dev/docs/getting-started) - a **guided tour** of the React Native **basics**.
96
+ - [Blog](https://reactnative.dev/blog) - read the latest official React Native **Blog** posts.
97
+ - [`@facebook/react-native`](https://github.com/facebook/react-native) - the Open Source; GitHub **repository** for React Native.
File without changes
@@ -0,0 +1,2 @@
1
+ #Tue Nov 25 14:33:26 IST 2025
2
+ gradle.version=8.9
File without changes
@@ -1,20 +1,21 @@
1
1
  apply plugin: 'com.android.library'
2
2
 
3
- def safeExtGet(prop, fallback) {
4
- rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
5
- }
6
-
7
3
  android {
8
- compileSdkVersion safeExtGet('compileSdkVersion', 28)
9
-
4
+ namespace "com.cometchat.calls"
5
+ compileSdkVersion rootProject.ext.compileSdkVersion
6
+
10
7
  defaultConfig {
11
- minSdkVersion safeExtGet('minSdkVersion', 16)
12
- targetSdkVersion safeExtGet('targetSdkVersion', 28)
13
- versionCode 1
14
- versionName "1.0"
8
+ minSdkVersion rootProject.ext.minSdkVersion
9
+ targetSdkVersion rootProject.ext.targetSdkVersion
10
+ }
11
+
12
+ sourceSets {
13
+ main {
14
+ java.srcDirs = ['src/main/java']
15
+ }
15
16
  }
16
17
  }
17
18
 
18
19
  dependencies {
19
- implementation 'com.facebook.react:react-native:+'
20
- }
20
+ implementation "com.facebook.react:react-native:+"
21
+ }
@@ -1,8 +1,17 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.cometchat.calls">
1
2
 
2
- <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.CometChatCalls">
3
- <uses-permission android:name="android.permission.INTERNET" />
4
- <uses-permission android:name="android.permission.CAMERA" />
5
- <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
6
- <uses-permission android:name="android.permission.RECORD_AUDIO" />
7
- <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
3
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
4
+ <uses-permission android:name="android.permission.BLUETOOTH" />
5
+ <uses-permission android:name="android.permission.CAMERA" />
6
+ <uses-permission android:name="android.permission.INTERNET" />
7
+ <uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
8
+ <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
9
+ <uses-permission android:name="android.permission.RECORD_AUDIO" />
10
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
11
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
12
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
13
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" />
14
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
15
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />
16
+ <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
8
17
  </manifest>
@@ -0,0 +1,185 @@
1
+ /*
2
+ * Copyright @ 2017-present 8x8, Inc.
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.cometchat.calls;
18
+
19
+ import android.media.AudioManager;
20
+ import android.os.Build;
21
+ import android.telecom.CallAudioState;
22
+
23
+ import androidx.annotation.RequiresApi;
24
+
25
+ import com.cometchat.calls.utils.CometChatLogger;
26
+
27
+ import java.util.HashSet;
28
+ import java.util.Set;
29
+
30
+
31
+ /**
32
+ * {@link AudioModeModule.AudioDeviceHandlerInterface} module implementing device handling for
33
+ * Android versions >= O when ConnectionService is enabled.
34
+ */
35
+ @RequiresApi(Build.VERSION_CODES.O)
36
+ class AudioDeviceHandlerConnectionService implements
37
+ AudioModeModule.AudioDeviceHandlerInterface,
38
+ RNConnectionService.CallAudioStateListener {
39
+
40
+ private final static String TAG = AudioDeviceHandlerConnectionService.class.getSimpleName();
41
+
42
+ /**
43
+ * {@link AudioManager} instance used to interact with the Android audio subsystem.
44
+ */
45
+ private AudioManager audioManager;
46
+
47
+ /**
48
+ * Reference to the main {@code AudioModeModule}.
49
+ */
50
+ private AudioModeModule module;
51
+
52
+ private RNConnectionService rcs;
53
+
54
+ /**
55
+ * Converts any of the "DEVICE_" constants into the corresponding
56
+ * {@link CallAudioState} "ROUTE_" number.
57
+ *
58
+ * @param audioDevice one of the "DEVICE_" constants.
59
+ * @return a route number {@link CallAudioState#ROUTE_EARPIECE} if
60
+ * no match is found.
61
+ */
62
+ private static int audioDeviceToRouteInt(String audioDevice) {
63
+ if (audioDevice == null) {
64
+ return CallAudioState.ROUTE_SPEAKER;
65
+ }
66
+ switch (audioDevice) {
67
+ case AudioModeModule.DEVICE_BLUETOOTH:
68
+ return CallAudioState.ROUTE_BLUETOOTH;
69
+ case AudioModeModule.DEVICE_EARPIECE:
70
+ return CallAudioState.ROUTE_EARPIECE;
71
+ case AudioModeModule.DEVICE_HEADPHONES:
72
+ return CallAudioState.ROUTE_WIRED_HEADSET;
73
+ case AudioModeModule.DEVICE_SPEAKER:
74
+ return CallAudioState.ROUTE_SPEAKER;
75
+ default:
76
+ CometChatLogger.e(TAG, "Unsupported device name: " + audioDevice);
77
+ return CallAudioState.ROUTE_SPEAKER;
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Populates given route mask into the "DEVICE_" list.
83
+ *
84
+ * @param supportedRouteMask an integer coming from
85
+ * {@link CallAudioState#getSupportedRouteMask()}.
86
+ * @return a list of device names.
87
+ */
88
+ private static Set<String> routesToDeviceNames(int supportedRouteMask) {
89
+ Set<String> devices = new HashSet<>();
90
+ if ((supportedRouteMask & CallAudioState.ROUTE_EARPIECE) == CallAudioState.ROUTE_EARPIECE) {
91
+ devices.add(AudioModeModule.DEVICE_EARPIECE);
92
+ }
93
+ if ((supportedRouteMask & CallAudioState.ROUTE_BLUETOOTH) == CallAudioState.ROUTE_BLUETOOTH) {
94
+ devices.add(AudioModeModule.DEVICE_BLUETOOTH);
95
+ }
96
+ if ((supportedRouteMask & CallAudioState.ROUTE_SPEAKER) == CallAudioState.ROUTE_SPEAKER) {
97
+ devices.add(AudioModeModule.DEVICE_SPEAKER);
98
+ }
99
+ if ((supportedRouteMask & CallAudioState.ROUTE_WIRED_HEADSET) == CallAudioState.ROUTE_WIRED_HEADSET) {
100
+ devices.add(AudioModeModule.DEVICE_HEADPHONES);
101
+ }
102
+ return devices;
103
+ }
104
+
105
+ /**
106
+ * Used to store the most recently reported audio devices.
107
+ * Makes it easier to compare for a change, because the devices are stored
108
+ * as a mask in the {@link CallAudioState}. The mask is populated into
109
+ * the {@code availableDevices} on each update.
110
+ */
111
+ private int supportedRouteMask = -1;
112
+
113
+ public AudioDeviceHandlerConnectionService(AudioManager audioManager) {
114
+ this.audioManager = audioManager;
115
+ }
116
+
117
+ @Override
118
+ public void onCallAudioStateChange(final CallAudioState state) {
119
+ module.runInAudioThread(new Runnable() {
120
+ @Override
121
+ public void run() {
122
+ boolean audioRouteChanged
123
+ = audioDeviceToRouteInt(module.getSelectedDevice()) != state.getRoute();
124
+ int newSupportedRoutes = state.getSupportedRouteMask();
125
+ boolean audioDevicesChanged = supportedRouteMask != newSupportedRoutes;
126
+ if (audioDevicesChanged) {
127
+ supportedRouteMask = newSupportedRoutes;
128
+ Set<String> devices = routesToDeviceNames(supportedRouteMask);
129
+ module.replaceDevices(devices);
130
+ CometChatLogger.i(TAG, "Available audio devices: " + devices.toString());
131
+ }
132
+
133
+ if (audioRouteChanged || audioDevicesChanged) {
134
+ module.resetSelectedDevice();
135
+ module.updateAudioRoute();
136
+ }
137
+ }
138
+ });
139
+ }
140
+
141
+ @Override
142
+ public void start(AudioModeModule audioModeModule) {
143
+ CometChatLogger.i(TAG, "Using " + TAG + " as the audio device handler");
144
+
145
+ module = audioModeModule;
146
+ rcs = module.getContext().getNativeModule(RNConnectionService.class);
147
+
148
+ if (rcs != null) {
149
+ rcs.setCallAudioStateListener(this);
150
+ } else {
151
+ CometChatLogger.w(TAG, "Couldn't set call audio state listener, module is null");
152
+ }
153
+ }
154
+
155
+ @Override
156
+ public void stop() {
157
+ if (rcs != null) {
158
+ rcs.setCallAudioStateListener(null);
159
+ rcs = null;
160
+ } else {
161
+ CometChatLogger.w(TAG, "Couldn't set call audio state listener, module is null");
162
+ }
163
+ }
164
+
165
+ public void setAudioRoute(String audioDevice) {
166
+ int newAudioRoute = audioDeviceToRouteInt(audioDevice);
167
+
168
+ RNConnectionService.setAudioRoute(newAudioRoute);
169
+ }
170
+
171
+ @Override
172
+ public boolean setMode(int mode) {
173
+ if (mode != AudioModeModule.DEFAULT) {
174
+ // This shouldn't be needed when using ConnectionService, but some devices have been
175
+ // observed not doing it.
176
+ try {
177
+ audioManager.setMicrophoneMute(false);
178
+ } catch (Throwable tr) {
179
+ CometChatLogger.w(TAG, "Failed to unmute the microphone");
180
+ }
181
+ }
182
+
183
+ return true;
184
+ }
185
+ }
@@ -0,0 +1,254 @@
1
+ /*
2
+ * Copyright @ 2017-present 8x8, Inc.
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.cometchat.calls;
18
+
19
+ import android.media.AudioAttributes;
20
+ import android.media.AudioDeviceInfo;
21
+ import android.media.AudioFocusRequest;
22
+ import android.media.AudioManager;
23
+ import android.os.Build;
24
+
25
+ import com.cometchat.calls.utils.CometChatLogger;
26
+
27
+ import java.util.HashSet;
28
+ import java.util.Set;
29
+
30
+
31
+ /**
32
+ * {@link AudioModeModule.AudioDeviceHandlerInterface} module implementing device handling for
33
+ * all post-M Android versions. This handler can be used on any Android versions >= M, but by
34
+ * default it's only used on versions < O, since versions >= O use ConnectionService, but it
35
+ * can be disabled.
36
+ */
37
+ class AudioDeviceHandlerGeneric implements
38
+ AudioModeModule.AudioDeviceHandlerInterface,
39
+ AudioManager.OnAudioFocusChangeListener {
40
+
41
+ private final static String TAG = AudioDeviceHandlerGeneric.class.getSimpleName();
42
+
43
+ /**
44
+ * Reference to the main {@code AudioModeModule}.
45
+ */
46
+ private AudioModeModule module;
47
+
48
+ /**
49
+ * Constant defining a Hearing Aid. Only available on API level >= 28.
50
+ * The value of: AudioDeviceInfo.TYPE_HEARING_AID
51
+ */
52
+ private static final int TYPE_HEARING_AID = 23;
53
+
54
+ /**
55
+ * Constant defining a USB headset. Only available on API level >= 26.
56
+ * The value of: AudioDeviceInfo.TYPE_USB_HEADSET
57
+ */
58
+ private static final int TYPE_USB_HEADSET = 22;
59
+
60
+ /**
61
+ * Indicator that we have lost audio focus.
62
+ */
63
+ private boolean audioFocusLost = false;
64
+
65
+ /**
66
+ * {@link AudioManager} instance used to interact with the Android audio
67
+ * subsystem.
68
+ */
69
+ private AudioManager audioManager;
70
+
71
+ /**
72
+ * {@link Runnable} for running audio device detection in the audio thread.
73
+ * This is only used on Android >= M.
74
+ */
75
+ private final Runnable onAudioDeviceChangeRunner = new Runnable() {
76
+ @Override
77
+ public void run() {
78
+ Set<String> devices = new HashSet<>();
79
+ AudioDeviceInfo[] deviceInfos = audioManager.getDevices( AudioManager.GET_DEVICES_INPUTS | AudioManager.GET_DEVICES_OUTPUTS);
80
+
81
+ for (AudioDeviceInfo info: deviceInfos) {
82
+ switch (info.getType()) {
83
+ case AudioDeviceInfo.TYPE_BLUETOOTH_SCO:
84
+ devices.add(AudioModeModule.DEVICE_BLUETOOTH);
85
+ break;
86
+ case AudioDeviceInfo.TYPE_BUILTIN_EARPIECE:
87
+ devices.add(AudioModeModule.DEVICE_EARPIECE);
88
+ break;
89
+ case AudioDeviceInfo.TYPE_BUILTIN_SPEAKER:
90
+ case AudioDeviceInfo.TYPE_HDMI:
91
+ devices.add(AudioModeModule.DEVICE_SPEAKER);
92
+ break;
93
+ case AudioDeviceInfo.TYPE_WIRED_HEADPHONES:
94
+ case AudioDeviceInfo.TYPE_WIRED_HEADSET:
95
+ case TYPE_HEARING_AID:
96
+ case TYPE_USB_HEADSET:
97
+ devices.add(AudioModeModule.DEVICE_HEADPHONES);
98
+ break;
99
+ }
100
+ }
101
+
102
+ module.replaceDevices(devices);
103
+
104
+ CometChatLogger.i(TAG, "Available audio devices: " + devices.toString());
105
+
106
+ module.updateAudioRoute();
107
+ }
108
+ };
109
+
110
+ private final android.media.AudioDeviceCallback audioDeviceCallback =
111
+ new android.media.AudioDeviceCallback() {
112
+ @Override
113
+ public void onAudioDevicesAdded(
114
+ AudioDeviceInfo[] addedDevices) {
115
+ CometChatLogger.d(TAG, "Audio devices added");
116
+ onAudioDeviceChange();
117
+ }
118
+
119
+ @Override
120
+ public void onAudioDevicesRemoved(
121
+ AudioDeviceInfo[] removedDevices) {
122
+ CometChatLogger.d(TAG, "Audio devices removed");
123
+ onAudioDeviceChange();
124
+ }
125
+ };
126
+
127
+ public AudioDeviceHandlerGeneric(AudioManager audioManager) {
128
+ this.audioManager = audioManager;
129
+ }
130
+
131
+ /**
132
+ * Helper method to trigger an audio route update when devices change. It
133
+ * makes sure the operation is performed on the audio thread.
134
+ */
135
+ private void onAudioDeviceChange() {
136
+ module.runInAudioThread(onAudioDeviceChangeRunner);
137
+ }
138
+
139
+ /**
140
+ * {@link AudioManager.OnAudioFocusChangeListener} interface method. Called
141
+ * when the audio focus of the system is updated.
142
+ *
143
+ * @param focusChange - The type of focus change.
144
+ */
145
+ @Override
146
+ public void onAudioFocusChange(final int focusChange) {
147
+ module.runInAudioThread(new Runnable() {
148
+ @Override
149
+ public void run() {
150
+ switch (focusChange) {
151
+ case AudioManager.AUDIOFOCUS_GAIN: {
152
+ CometChatLogger.d(TAG, "Audio focus gained");
153
+ // Some other application potentially stole our audio focus
154
+ // temporarily. Restore our mode.
155
+ if (audioFocusLost) {
156
+ module.resetAudioRoute();
157
+ }
158
+ audioFocusLost = false;
159
+ break;
160
+ }
161
+ case AudioManager.AUDIOFOCUS_LOSS:
162
+ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
163
+ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: {
164
+ CometChatLogger.d(TAG, "Audio focus lost");
165
+ audioFocusLost = true;
166
+ break;
167
+ }
168
+ }
169
+ }
170
+ });
171
+ }
172
+
173
+ /**
174
+ * Helper method to set the output route to a Bluetooth device.
175
+ *
176
+ * @param enabled true if Bluetooth should use used, false otherwise.
177
+ */
178
+ private void setBluetoothAudioRoute(boolean enabled) {
179
+ if (enabled) {
180
+ audioManager.startBluetoothSco();
181
+ audioManager.setBluetoothScoOn(true);
182
+ } else {
183
+ audioManager.setBluetoothScoOn(false);
184
+ audioManager.stopBluetoothSco();
185
+ }
186
+ }
187
+
188
+ @Override
189
+ public void start(AudioModeModule audioModeModule) {
190
+ CometChatLogger.i(TAG, "Using " + TAG + " as the audio device handler");
191
+
192
+ module = audioModeModule;
193
+
194
+ // Setup runtime device change detection.
195
+ audioManager.registerAudioDeviceCallback(audioDeviceCallback, null);
196
+
197
+ // Do an initial detection.
198
+ onAudioDeviceChange();
199
+ }
200
+
201
+ @Override
202
+ public void stop() {
203
+ audioManager.unregisterAudioDeviceCallback(audioDeviceCallback);
204
+ }
205
+
206
+ @Override
207
+ public void setAudioRoute(String device) {
208
+ // Turn speaker on / off
209
+ audioManager.setSpeakerphoneOn(device.equals(AudioModeModule.DEVICE_SPEAKER));
210
+
211
+ // Turn bluetooth on / off
212
+ setBluetoothAudioRoute(device.equals(AudioModeModule.DEVICE_BLUETOOTH));
213
+ }
214
+
215
+ @Override
216
+ public boolean setMode(int mode) {
217
+ if (mode == AudioModeModule.DEFAULT) {
218
+ audioFocusLost = false;
219
+ audioManager.setMode(AudioManager.MODE_NORMAL);
220
+ audioManager.abandonAudioFocus(this);
221
+ audioManager.setSpeakerphoneOn(false);
222
+ setBluetoothAudioRoute(false);
223
+
224
+ return true;
225
+ }
226
+
227
+ audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
228
+ audioManager.setMicrophoneMute(false);
229
+
230
+ int gotFocus;
231
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
232
+ gotFocus = audioManager.requestAudioFocus(new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
233
+ .setAudioAttributes(
234
+ new AudioAttributes.Builder()
235
+ .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
236
+ .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
237
+ .build()
238
+ )
239
+ .setAcceptsDelayedFocusGain(true)
240
+ .setOnAudioFocusChangeListener(this)
241
+ .build()
242
+ );
243
+ } else {
244
+ gotFocus = audioManager.requestAudioFocus(this, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN);
245
+ }
246
+
247
+ if (gotFocus == AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
248
+ CometChatLogger.w(TAG, "Audio focus request failed");
249
+ return false;
250
+ }
251
+
252
+ return true;
253
+ }
254
+ }