@cometchat/calls-sdk-react-native 4.0.0-beta1

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 (50) hide show
  1. package/README.md +27 -0
  2. package/android/build.gradle +20 -0
  3. package/android/src/main/AndroidManifest.xml +8 -0
  4. package/android/src/main/java/com/CometChatCalls/AudioDeviceHandlerGeneric.java +213 -0
  5. package/android/src/main/java/com/CometChatCalls/AudioDeviceHandlerLegacy.java +213 -0
  6. package/android/src/main/java/com/CometChatCalls/AudioModeModule.java +456 -0
  7. package/android/src/main/java/com/CometChatCalls/BluetoothHeadsetMonitor.java +174 -0
  8. package/android/src/main/java/com/CometChatCalls/CometChatCallsPackage.java +45 -0
  9. package/cometchat-calls-sdk-react-native.podspec +21 -0
  10. package/dist/CometChatErrorConstants.d.ts +124 -0
  11. package/dist/Constants.d.ts +720 -0
  12. package/dist/Helper copy.d.ts +1 -0
  13. package/dist/Helper.d.ts +7 -0
  14. package/dist/api/APIHandler.d.ts +6 -0
  15. package/dist/api/endpoints.d.ts +6 -0
  16. package/dist/api/helper.d.ts +63 -0
  17. package/dist/api/index.d.ts +2 -0
  18. package/dist/constants/CallConstants.d.ts +136 -0
  19. package/dist/constants/index.d.ts +1 -0
  20. package/dist/defaultCallsettings.d.ts +2 -0
  21. package/dist/index.d.ts +3 -0
  22. package/dist/index.js +128 -0
  23. package/dist/models/CallAppSettings.d.ts +42 -0
  24. package/dist/models/CallSettings.d.ts +316 -0
  25. package/dist/models/CometChatCalls.d.ts +89 -0
  26. package/dist/models/CometChatCallsComponent.d.ts +13 -0
  27. package/dist/models/CometChatCallsComponentCore.d.ts +18 -0
  28. package/dist/models/CometChatCallsException.d.ts +7 -0
  29. package/dist/models/CometChatPresenterComponent.d.ts +13 -0
  30. package/dist/models/ErrorModel.d.ts +11 -0
  31. package/dist/models/Listner.d.ts +64 -0
  32. package/dist/models/ListnerHandler.d.ts +10 -0
  33. package/dist/models/MessageComponent.d.ts +7 -0
  34. package/dist/models/PresenterSettings.d.ts +194 -0
  35. package/dist/models/RTCUser.d.ts +18 -0
  36. package/dist/models/index.d.ts +7 -0
  37. package/dist/types/ICallAppSettings.d.ts +6 -0
  38. package/dist/types/ICallSettings.d.ts +60 -0
  39. package/dist/types/RTCUser.d.ts +6 -0
  40. package/dist/types/callEvents.d.ts +53 -0
  41. package/dist/types/common.d.ts +17 -0
  42. package/dist/types/index.d.ts +2 -0
  43. package/ios/AudioMode.h +11 -0
  44. package/ios/AudioMode.m +403 -0
  45. package/ios/JitsiAudioSession+Private.h +25 -0
  46. package/ios/JitsiAudioSession.h +17 -0
  47. package/ios/JitsiAudioSession.m +34 -0
  48. package/ios/LogUtils.h +23 -0
  49. package/ios/react-native-calls2.xcodeproj/project.pbxproj +269 -0
  50. package/package.json +122 -0
@@ -0,0 +1,456 @@
1
+ package com.CometChatCalls;
2
+
3
+ import android.content.Context;
4
+ import android.media.AudioManager;
5
+ import android.os.Build;
6
+ import android.util.Log;
7
+
8
+ import com.facebook.react.bridge.Arguments;
9
+ import com.facebook.react.bridge.Promise;
10
+ import com.facebook.react.bridge.ReactApplicationContext;
11
+ import com.facebook.react.bridge.ReactContextBaseJavaModule;
12
+ import com.facebook.react.bridge.ReactMethod;
13
+ import com.facebook.react.bridge.WritableArray;
14
+ import com.facebook.react.bridge.WritableMap;
15
+ import com.facebook.react.modules.core.DeviceEventManagerModule;
16
+
17
+ import java.util.HashMap;
18
+ import java.util.HashSet;
19
+ import java.util.Map;
20
+ import java.util.Set;
21
+ import java.util.concurrent.ExecutorService;
22
+ import java.util.concurrent.Executors;
23
+
24
+ /**
25
+ * Module implementing a simple API to select the appropriate audio device for a
26
+ * conference call.
27
+ *
28
+ * Audio calls should use {@code AudioModeModule.AUDIO_CALL}, which uses the
29
+ * builtin earpiece, wired headset or bluetooth headset. The builtin earpiece is
30
+ * the default audio device.
31
+ *
32
+ * Video calls should should use {@code AudioModeModule.VIDEO_CALL}, which uses
33
+ * the builtin speaker, earpiece, wired headset or bluetooth headset. The
34
+ * builtin speaker is the default audio device.
35
+ *
36
+ * Before a call has started and after it has ended the
37
+ * {@code AudioModeModule.DEFAULT} mode should be used.
38
+ */
39
+ class AudioModeModule extends ReactContextBaseJavaModule {
40
+ public static final String NAME = "AudioMode";
41
+
42
+ /**
43
+ * Constants representing the audio mode.
44
+ * - DEFAULT: Used before and after every call. It represents the default
45
+ * audio routing scheme.
46
+ * - AUDIO_CALL: Used for audio only calls. It will use the earpiece by
47
+ * default, unless a wired or Bluetooth headset is connected.
48
+ * - VIDEO_CALL: Used for video calls. It will use the speaker by default,
49
+ * unless a wired or Bluetooth headset is connected.
50
+ */
51
+ static final int DEFAULT = 0;
52
+ static final int AUDIO_CALL = 1;
53
+ static final int VIDEO_CALL = 2;
54
+
55
+ /**
56
+ * The {@code Log} tag {@code AudioModeModule} is to log messages with.
57
+ */
58
+ static final String TAG = NAME;
59
+
60
+ /**
61
+ * Whether or not the ConnectionService is used for selecting audio devices.
62
+ */
63
+
64
+ private static final boolean supportsConnectionService = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
65
+ private static boolean useConnectionService_ = false;
66
+
67
+ static boolean useConnectionService() {
68
+ return supportsConnectionService && useConnectionService_;
69
+ }
70
+
71
+ /**
72
+ * {@link AudioManager} instance used to interact with the Android audio
73
+ * subsystem.
74
+ */
75
+ private AudioManager audioManager;
76
+
77
+ private AudioDeviceHandlerInterface audioDeviceHandler;
78
+
79
+ /**
80
+ * {@link ExecutorService} for running all audio operations on a dedicated
81
+ * thread.
82
+ */
83
+ private static final ExecutorService executor = Executors.newSingleThreadExecutor();
84
+
85
+ /**
86
+ * Audio mode currently in use.
87
+ */
88
+ private int mode = -1;
89
+
90
+ /**
91
+ * Audio device types.
92
+ */
93
+ static final String DEVICE_BLUETOOTH = "BLUETOOTH";
94
+ static final String DEVICE_EARPIECE = "EARPIECE";
95
+ static final String DEVICE_HEADPHONES = "HEADPHONES";
96
+ static final String DEVICE_SPEAKER = "SPEAKER";
97
+
98
+ /**
99
+ * Device change event.
100
+ */
101
+ private static final String DEVICE_CHANGE_EVENT = "org.jitsi.meet:features/audio-mode#devices-update";
102
+
103
+ /**
104
+ * List of currently available audio devices.
105
+ */
106
+ private Set<String> availableDevices = new HashSet<>();
107
+
108
+ /**
109
+ * Currently selected device.
110
+ */
111
+ private String selectedDevice;
112
+
113
+ /**
114
+ * User selected device. When null the default is used depending on the
115
+ * mode.
116
+ */
117
+ private String userSelectedDevice;
118
+
119
+ private ReactApplicationContext reactContext;
120
+ /**
121
+ * Initializes a new module instance. There shall be a single instance of
122
+ * this module throughout the lifetime of the application.
123
+ *
124
+ * @param reactContext the {@link ReactApplicationContext} where this module
125
+ * is created.
126
+ */
127
+ public AudioModeModule(ReactApplicationContext reactContext) {
128
+ super(reactContext);
129
+
130
+ this.reactContext = reactContext;
131
+ audioManager = (AudioManager) reactContext.getSystemService(Context.AUDIO_SERVICE);
132
+ audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
133
+ }
134
+
135
+ /**
136
+ * Gets a mapping with the constants this module is exporting.
137
+ *
138
+ * @return a {@link Map} mapping the constants to be exported with their
139
+ * values.
140
+ */
141
+ @Override
142
+ public Map<String, Object> getConstants() {
143
+ Map<String, Object> constants = new HashMap<>();
144
+
145
+ constants.put("DEVICE_CHANGE_EVENT", DEVICE_CHANGE_EVENT);
146
+ constants.put("AUDIO_CALL", AUDIO_CALL);
147
+ constants.put("DEFAULT", DEFAULT);
148
+ constants.put("VIDEO_CALL", VIDEO_CALL);
149
+
150
+ return constants;
151
+ }
152
+
153
+ /**
154
+ * Notifies JS land that the devices list has changed.
155
+ */
156
+ private void notifyDevicesChanged() {
157
+ runInAudioThread(new Runnable() {
158
+ @Override
159
+ public void run() {
160
+ WritableArray data = Arguments.createArray();
161
+ final boolean hasHeadphones = availableDevices.contains(DEVICE_HEADPHONES);
162
+ Log.e(TAG, "hasHeadphones ? " + hasHeadphones);
163
+ for (String device : availableDevices) {
164
+ if (hasHeadphones && device.equals(DEVICE_EARPIECE)) {
165
+ // Skip earpiece when headphones are plugged in.
166
+ continue;
167
+ }
168
+ WritableMap deviceInfo = Arguments.createMap();
169
+ deviceInfo.putString("type", device);
170
+ deviceInfo.putBoolean("selected", device.equals(selectedDevice));
171
+ data.pushMap(deviceInfo);
172
+ }
173
+ reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
174
+ .emit(DEVICE_CHANGE_EVENT, data);
175
+ }
176
+ });
177
+ }
178
+
179
+ /**
180
+ * Gets the name for this module to be used in the React Native bridge.
181
+ *
182
+ * @return a string with the module name.
183
+ */
184
+ @Override
185
+ public String getName() {
186
+ return NAME;
187
+ }
188
+
189
+ @Override
190
+ public void initialize() {
191
+ runInAudioThread(new Runnable() {
192
+ @Override
193
+ public void run() {
194
+ setAudioDeviceHandler();
195
+ }
196
+ });
197
+ }
198
+
199
+ private void setAudioDeviceHandler() {
200
+ if (audioDeviceHandler != null) {
201
+ audioDeviceHandler.stop();
202
+ }
203
+
204
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
205
+ audioDeviceHandler = new AudioDeviceHandlerGeneric(audioManager);
206
+ } else {
207
+ audioDeviceHandler = new AudioDeviceHandlerLegacy(audioManager);
208
+ }
209
+
210
+ audioDeviceHandler.start(this);
211
+ }
212
+
213
+ /**
214
+ * Helper function to run operations on a dedicated thread.
215
+ *
216
+ * @param runnable
217
+ */
218
+ void runInAudioThread(Runnable runnable) {
219
+ executor.execute(runnable);
220
+ }
221
+
222
+ /**
223
+ * Sets the user selected audio device as the active audio device.
224
+ *
225
+ * @param device the desired device which will become active.
226
+ */
227
+ @ReactMethod
228
+ public void setAudioDevice(final String device) {
229
+ runInAudioThread(new Runnable() {
230
+ @Override
231
+ public void run() {
232
+ Log.e(TAG, "Selected Devices = " + device);
233
+ Log.e(TAG, "Available Devices = " + availableDevices);
234
+ if (availableDevices != null && device != null) {
235
+ if (!availableDevices.contains(device)) {
236
+ userSelectedDevice = null;
237
+ return;
238
+ }
239
+
240
+ if (mode != -1) {
241
+ userSelectedDevice = device;
242
+ updateAudioRoute(mode);
243
+ }
244
+ }
245
+ }
246
+ });
247
+ }
248
+
249
+ @ReactMethod
250
+ public void getAllDevices() {
251
+ Log.e("getAllDevices","getAllDevices");
252
+ notifyDevicesChanged();
253
+ }
254
+ /**
255
+ * Public method to set the current audio mode.
256
+ *
257
+ * @param mode the desired audio mode.
258
+ * @param promise a {@link Promise} which will be resolved if the audio mode
259
+ * could be updated successfully, and it will be rejected
260
+ * otherwise.
261
+ */
262
+ @ReactMethod
263
+ public void setMode(final int mode, final Promise promise) {
264
+ if (mode != DEFAULT && mode != AUDIO_CALL && mode != VIDEO_CALL) {
265
+ promise.reject("setMode", "Invalid audio mode " + mode);
266
+ return;
267
+ }
268
+
269
+ runInAudioThread(new Runnable() {
270
+ @Override
271
+ public void run() {
272
+ boolean success;
273
+
274
+ try {
275
+ success = updateAudioRoute(mode);
276
+ } catch (Throwable e) {
277
+ success = false;
278
+ }
279
+ if (success) {
280
+ AudioModeModule.this.mode = mode;
281
+ promise.resolve(null);
282
+ } else {
283
+ promise.reject("setMode", "Failed to set audio mode to " + mode);
284
+ }
285
+ }
286
+ });
287
+ }
288
+
289
+ /**
290
+ * Sets whether ConnectionService should be used (if available) for setting the
291
+ * audio mode
292
+ * or not.
293
+ *
294
+ * @param use Boolean indicator of where it should be used or not.
295
+ */
296
+ @ReactMethod
297
+ public void setUseConnectionService(final boolean use) {
298
+ runInAudioThread(new Runnable() {
299
+ @Override
300
+ public void run() {
301
+ useConnectionService_ = use;
302
+ setAudioDeviceHandler();
303
+ }
304
+ });
305
+ }
306
+
307
+ /**
308
+ * Updates the audio route for the given mode.
309
+ *
310
+ * @param mode the audio mode to be used when computing the audio route.
311
+ * @return {@code true} if the audio route was updated successfully;
312
+ * {@code false}, otherwise.
313
+ */
314
+ private boolean updateAudioRoute(int mode) {
315
+
316
+ if (!audioDeviceHandler.setMode(mode)) {
317
+ return false;
318
+ }
319
+
320
+ if (mode == DEFAULT) {
321
+ selectedDevice = null;
322
+ userSelectedDevice = null;
323
+
324
+ notifyDevicesChanged();
325
+ return true;
326
+ }
327
+
328
+ boolean bluetoothAvailable = availableDevices.contains(DEVICE_BLUETOOTH);
329
+ boolean headsetAvailable = availableDevices.contains(DEVICE_HEADPHONES);
330
+
331
+ // Pick the desired device based on what's available and the mode.
332
+ String audioDevice;
333
+ if (bluetoothAvailable) {
334
+ audioDevice = DEVICE_BLUETOOTH;
335
+ } else if (headsetAvailable) {
336
+ audioDevice = DEVICE_HEADPHONES;
337
+ } else {
338
+ audioDevice = DEVICE_SPEAKER;
339
+ }
340
+
341
+ // Consider the user's selection
342
+ if (userSelectedDevice != null && availableDevices.contains(userSelectedDevice)) {
343
+ audioDevice = userSelectedDevice;
344
+ }
345
+
346
+ // If the previously selected device and the current default one
347
+ // match, do nothing.
348
+ if (selectedDevice != null && selectedDevice.equals(audioDevice)) {
349
+ return true;
350
+ }
351
+
352
+ selectedDevice = audioDevice;
353
+
354
+ audioDeviceHandler.setAudioRoute(audioDevice);
355
+
356
+ notifyDevicesChanged();
357
+ return true;
358
+ }
359
+
360
+ /**
361
+ * Gets the currently selected audio device.
362
+ *
363
+ * @return The selected audio device.
364
+ */
365
+ String getSelectedDevice() {
366
+ return selectedDevice;
367
+ }
368
+
369
+ /**
370
+ * Resets the current device selection.
371
+ */
372
+ void resetSelectedDevice() {
373
+ selectedDevice = null;
374
+ userSelectedDevice = null;
375
+ }
376
+
377
+ /**
378
+ * Adds a new device to the list of available devices.
379
+ *
380
+ * @param device The new device.
381
+ */
382
+ void addDevice(String device) {
383
+ availableDevices.add(device);
384
+ resetSelectedDevice();
385
+ }
386
+
387
+ /**
388
+ * Removes a device from the list of available devices.
389
+ *
390
+ * @param device The old device to the removed.
391
+ */
392
+ void removeDevice(String device) {
393
+ availableDevices.remove(device);
394
+ resetSelectedDevice();
395
+ }
396
+
397
+ /**
398
+ * Replaces the current list of available devices with a new one.
399
+ *
400
+ * @param devices The new devices list.
401
+ */
402
+ void replaceDevices(Set<String> devices) {
403
+ availableDevices = devices;
404
+ resetSelectedDevice();
405
+ }
406
+
407
+ /**
408
+ * Re-sets the current audio route. Needed when devices changes have happened.
409
+ */
410
+ void updateAudioRoute() {
411
+ if (mode != -1) {
412
+ updateAudioRoute(mode);
413
+ }
414
+ }
415
+
416
+ /**
417
+ * Needed on the legacy handler...
418
+ *
419
+ * @return Context for the application.
420
+ */
421
+ Context getContext() {
422
+ return getReactApplicationContext();
423
+ }
424
+
425
+ /**
426
+ * Interface for the modules implementing the actual audio device management.
427
+ */
428
+ interface AudioDeviceHandlerInterface {
429
+ /**
430
+ * Start detecting audio device changes.
431
+ *
432
+ * @param audioModeModule Reference to the main {@link AudioModeModule}.
433
+ */
434
+ void start(AudioModeModule audioModeModule);
435
+
436
+ /**
437
+ * Stop audio device detection.
438
+ */
439
+ void stop();
440
+
441
+ /**
442
+ * Set the appropriate route for the given audio device.
443
+ *
444
+ * @param device Audio device for which the route must be set.
445
+ */
446
+ void setAudioRoute(String device);
447
+
448
+ /**
449
+ * Set the given audio mode.
450
+ *
451
+ * @param mode The new audio mode to be used.
452
+ * @return Whether the operation was successful or not.
453
+ */
454
+ boolean setMode(int mode);
455
+ }
456
+ }
@@ -0,0 +1,174 @@
1
+
2
+ package com.CometChatCalls;
3
+
4
+ import android.bluetooth.BluetoothAdapter;
5
+ import android.bluetooth.BluetoothHeadset;
6
+ import android.bluetooth.BluetoothProfile;
7
+ import android.content.BroadcastReceiver;
8
+ import android.content.Context;
9
+ import android.content.Intent;
10
+ import android.content.IntentFilter;
11
+ import android.media.AudioManager;
12
+ import android.util.Log;
13
+
14
+ /**
15
+ * Helper class to detect and handle Bluetooth device changes. It monitors
16
+ * Bluetooth headsets being connected / disconnected and notifies the module
17
+ * about device changes when this occurs.
18
+ */
19
+ class BluetoothHeadsetMonitor {
20
+ private final static String TAG = BluetoothHeadsetMonitor.class.getSimpleName();
21
+
22
+ /**
23
+ * The {@link Context} in which this module executes.
24
+ */
25
+ private final Context context;
26
+
27
+ /**
28
+ * Reference to the {@link BluetoothAdapter} object, used to access Bluetooth functionality.
29
+ */
30
+ private BluetoothAdapter adapter;
31
+
32
+ /**
33
+ * Reference to a proxy object which allows us to query connected devices.
34
+ */
35
+ private BluetoothHeadset headset;
36
+
37
+ /**
38
+ * receiver registered for receiving Bluetooth connection state changes.
39
+ */
40
+ private BroadcastReceiver receiver;
41
+
42
+ /**
43
+ * Listener for receiving Bluetooth device change events.
44
+ */
45
+ private Listener listener;
46
+
47
+ public BluetoothHeadsetMonitor(Context context, Listener listener) {
48
+ this.context = context;
49
+ this.listener = listener;
50
+ }
51
+
52
+ private boolean getBluetoothHeadsetProfileProxy() {
53
+ adapter = BluetoothAdapter.getDefaultAdapter();
54
+
55
+ if (adapter == null) {
56
+ return false;
57
+ }
58
+
59
+ // XXX: The profile listener listens for system services of the given
60
+ // type being available to the application. That is, if our Bluetooth
61
+ // adapter has the "headset" profile.
62
+ BluetoothProfile.ServiceListener listener
63
+ = new BluetoothProfile.ServiceListener() {
64
+ @Override
65
+ public void onServiceConnected(int profile, BluetoothProfile proxy) {
66
+ if (profile == BluetoothProfile.HEADSET) {
67
+ headset = (BluetoothHeadset) proxy;
68
+ updateDevices();
69
+ }
70
+ }
71
+
72
+ @Override
73
+ public void onServiceDisconnected(int profile) {
74
+ // The logic is the same as the logic of onServiceConnected.
75
+ onServiceConnected(profile, /* proxy */ null);
76
+ }
77
+ };
78
+
79
+ return adapter.getProfileProxy(context, listener, BluetoothProfile.HEADSET);
80
+ }
81
+
82
+ private void onBluetoothReceiverReceive(Context context, Intent intent) {
83
+ final String action = intent.getAction();
84
+
85
+ if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
86
+ // XXX: This action will be fired when a Bluetooth headset is
87
+ // connected or disconnected to the system. This is not related to
88
+ // audio routing.
89
+ int state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, -99);
90
+
91
+ switch (state) {
92
+ case BluetoothHeadset.STATE_CONNECTED:
93
+ case BluetoothHeadset.STATE_DISCONNECTED:
94
+ Log.d(TAG , " BT headset connection state changed: " + state);
95
+ updateDevices();
96
+ break;
97
+ }
98
+ } else if (action.equals(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)) {
99
+ // XXX: This action will be fired when the connection established
100
+ // with a Bluetooth headset (called a SCO connection) changes state.
101
+ // When the SCO connection is active we route audio to it.
102
+ int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -99);
103
+
104
+ switch (state) {
105
+ case AudioManager.SCO_AUDIO_STATE_CONNECTED:
106
+ case AudioManager.SCO_AUDIO_STATE_DISCONNECTED:
107
+ Log.d(TAG , " BT SCO connection state changed: " + state);
108
+ updateDevices();
109
+ break;
110
+ }
111
+ }
112
+ }
113
+
114
+ private void registerBluetoothReceiver() {
115
+ receiver = new BroadcastReceiver() {
116
+ @Override
117
+ public void onReceive(Context context, Intent intent) {
118
+ onBluetoothReceiverReceive(context, intent);
119
+ }
120
+ };
121
+
122
+ IntentFilter filter = new IntentFilter();
123
+ filter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
124
+ filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
125
+
126
+ context.registerReceiver(receiver, filter);
127
+ }
128
+
129
+ /**
130
+ * Detects if there are new devices connected / disconnected and fires the
131
+ * {@link Listener} registered event.
132
+ */
133
+ private void updateDevices() {
134
+ boolean headsetAvailable = (headset != null) && !headset.getConnectedDevices().isEmpty();
135
+ listener.onBluetoothDeviceChange(headsetAvailable);
136
+ }
137
+
138
+ public void start() {
139
+ AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
140
+
141
+ if (!audioManager.isBluetoothScoAvailableOffCall()) {
142
+ Log.w(TAG , " Bluetooth SCO is not available");
143
+ return;
144
+ }
145
+
146
+ if (!getBluetoothHeadsetProfileProxy()) {
147
+ Log.w(TAG , " Couldn't get BT profile proxy");
148
+ return;
149
+ }
150
+
151
+ registerBluetoothReceiver();
152
+
153
+ // Initial detection.
154
+ updateDevices();
155
+ }
156
+
157
+ public void stop() {
158
+ if (receiver != null) {
159
+ context.unregisterReceiver(receiver);
160
+ }
161
+
162
+ if (adapter != null && headset != null) {
163
+ adapter.closeProfileProxy(BluetoothProfile.HEADSET, headset);
164
+ }
165
+
166
+ receiver = null;
167
+ headset = null;
168
+ adapter = null;
169
+ }
170
+
171
+ interface Listener {
172
+ void onBluetoothDeviceChange(boolean deviceAvailable);
173
+ }
174
+ }
@@ -0,0 +1,45 @@
1
+ /*
2
+ * Copyright (c) 2017 Henry Lin @zxcpoiu
3
+ *
4
+ * Permission to use, copy, modify, and distribute this software for any
5
+ * purpose with or without fee is hereby granted, provided that the above
6
+ * copyright notice and this permission notice appear in all copies.
7
+ *
8
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
+ */
16
+
17
+ package com.CometChatCalls;
18
+
19
+ import com.facebook.react.ReactPackage;
20
+ import com.facebook.react.bridge.JavaScriptModule;
21
+ import com.facebook.react.bridge.NativeModule;
22
+ import com.facebook.react.bridge.ReactApplicationContext;
23
+ import com.facebook.react.uimanager.ViewManager;
24
+
25
+ import java.util.Collections;
26
+ import java.util.List;
27
+
28
+ public class CometChatCallsPackage implements ReactPackage {
29
+
30
+ @Override
31
+ public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
32
+ return Collections.<NativeModule>singletonList(new AudioModeModule(reactContext));
33
+ }
34
+
35
+ // Deprecated RN 0.47
36
+ public List<Class<? extends JavaScriptModule>> createJSModules() {
37
+ return Collections.emptyList();
38
+ }
39
+
40
+ @Override
41
+ public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
42
+ return Collections.emptyList();
43
+ }
44
+
45
+ }
@@ -0,0 +1,21 @@
1
+ require "json"
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = "cometchat-calls-sdk-react-native"
7
+ s.version = package["version"]
8
+ s.summary = package["description"]
9
+ s.homepage = package["homepage"]
10
+ s.license = package["license"]
11
+ s.authors = package["author"]
12
+
13
+ s.platforms = { :ios => "10.0" }
14
+ s.source = { :git => "https://github.com/cometchat-team/cometchat-pro-call-react-native", :tag => "#{s.version}" }
15
+
16
+ s.source_files = "ios/**/*.{h,m,mm}"
17
+
18
+ s.dependency "React-Core"
19
+
20
+ s.dependency "react-native-webrtc"
21
+ end