@capgo/capacitor-twilio-voice 7.2.13 → 7.2.16
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/src/main/java/ee/forgr/capacitor_twilio_voice/CapacitorTwilioVoicePlugin.java
CHANGED
|
@@ -270,12 +270,12 @@ public class CapacitorTwilioVoicePlugin extends Plugin {
|
|
|
270
270
|
|
|
271
271
|
// Delay the auto-accept slightly to ensure plugin is fully loaded
|
|
272
272
|
new android.os.Handler().postDelayed(
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
273
|
+
() -> {
|
|
274
|
+
Log.d(TAG, "Auto-accepting call: " + callSid);
|
|
275
|
+
ensureMicPermissionThenAccept(callSid);
|
|
276
|
+
},
|
|
277
|
+
500
|
|
278
|
+
);
|
|
279
279
|
}
|
|
280
280
|
}
|
|
281
281
|
}
|
|
@@ -309,20 +309,20 @@ public class CapacitorTwilioVoicePlugin extends Plugin {
|
|
|
309
309
|
if (callInvite != null) {
|
|
310
310
|
// Delay sending the event to ensure JavaScript is ready
|
|
311
311
|
new android.os.Handler().postDelayed(
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
312
|
+
() -> {
|
|
313
|
+
Log.d(TAG, "Sending incoming call event to JavaScript: " + callSid);
|
|
314
|
+
|
|
315
|
+
JSObject data = new JSObject();
|
|
316
|
+
data.put("callSid", callSid);
|
|
317
|
+
data.put("from", callFrom);
|
|
318
|
+
data.put("to", callInvite.getTo());
|
|
319
|
+
data.put("callerName", callerName != null ? callerName : callFrom);
|
|
320
|
+
data.put("openedFromNotification", true);
|
|
321
|
+
|
|
322
|
+
notifyListeners("callInviteReceived", data);
|
|
323
|
+
},
|
|
324
|
+
1000
|
|
325
|
+
); // Give JavaScript more time to initialize
|
|
326
326
|
} else {
|
|
327
327
|
Log.w(TAG, "Call invite not found for SID: " + callSid + " (may have been cancelled)");
|
|
328
328
|
}
|
|
@@ -62,7 +62,7 @@ public class CapacitorTwilioVoicePlugin: CAPPlugin, CAPBridgedPlugin, PushKitEve
|
|
|
62
62
|
deinit {
|
|
63
63
|
// Remove observers
|
|
64
64
|
NotificationCenter.default.removeObserver(self)
|
|
65
|
-
|
|
65
|
+
|
|
66
66
|
// CallKit has an odd API contract where the developer must call invalidate or the CXProvider is leaked.
|
|
67
67
|
if let provider = callKitProvider {
|
|
68
68
|
provider.invalidate()
|
|
@@ -100,23 +100,23 @@ public class CapacitorTwilioVoicePlugin: CAPPlugin, CAPBridgedPlugin, PushKitEve
|
|
|
100
100
|
private func setupAudioSession() {
|
|
101
101
|
do {
|
|
102
102
|
let audioSession = AVAudioSession.sharedInstance()
|
|
103
|
-
try audioSession.setCategory(.playAndRecord,
|
|
104
|
-
|
|
105
|
-
|
|
103
|
+
try audioSession.setCategory(.playAndRecord,
|
|
104
|
+
mode: .voiceChat,
|
|
105
|
+
options: [.allowBluetooth, .allowBluetoothA2DP, .allowAirPlay])
|
|
106
106
|
try audioSession.setActive(true)
|
|
107
107
|
NSLog("Audio session configured successfully")
|
|
108
108
|
} catch {
|
|
109
109
|
NSLog("Failed to configure audio session: \(error.localizedDescription)")
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
|
-
|
|
112
|
+
|
|
113
113
|
private func setupAudioDevice() {
|
|
114
114
|
TwilioVoiceSDK.audioDevice = audioDevice
|
|
115
115
|
|
|
116
116
|
// Set default audio routing to earpiece (not speaker)
|
|
117
117
|
toggleAudioRoute(toSpeaker: false)
|
|
118
118
|
}
|
|
119
|
-
|
|
119
|
+
|
|
120
120
|
private func setupNotifications() {
|
|
121
121
|
NotificationCenter.default.addObserver(
|
|
122
122
|
self,
|
|
@@ -124,7 +124,7 @@ public class CapacitorTwilioVoicePlugin: CAPPlugin, CAPBridgedPlugin, PushKitEve
|
|
|
124
124
|
name: AVAudioSession.mediaServicesWereResetNotification,
|
|
125
125
|
object: nil
|
|
126
126
|
)
|
|
127
|
-
|
|
127
|
+
|
|
128
128
|
NotificationCenter.default.addObserver(
|
|
129
129
|
self,
|
|
130
130
|
selector: #selector(handleAudioSessionInterruption),
|
|
@@ -132,34 +132,34 @@ public class CapacitorTwilioVoicePlugin: CAPPlugin, CAPBridgedPlugin, PushKitEve
|
|
|
132
132
|
object: nil
|
|
133
133
|
)
|
|
134
134
|
}
|
|
135
|
-
|
|
135
|
+
|
|
136
136
|
@objc private func handleMediaServicesReset() {
|
|
137
137
|
NSLog("Media services were reset, reconfiguring audio session")
|
|
138
138
|
setupAudioSession()
|
|
139
|
-
|
|
139
|
+
|
|
140
140
|
// Re-enable audio device
|
|
141
141
|
audioDevice.isEnabled = true
|
|
142
|
-
|
|
142
|
+
|
|
143
143
|
// Notify listeners about the reset
|
|
144
144
|
notifyListeners("audioSessionReset", data: nil)
|
|
145
145
|
}
|
|
146
|
-
|
|
146
|
+
|
|
147
147
|
@objc private func handleAudioSessionInterruption(notification: Notification) {
|
|
148
148
|
guard let userInfo = notification.userInfo,
|
|
149
149
|
let typeValue = userInfo[AVAudioSessionInterruptionTypeKey] as? UInt,
|
|
150
150
|
let type = AVAudioSession.InterruptionType(rawValue: typeValue) else {
|
|
151
151
|
return
|
|
152
152
|
}
|
|
153
|
-
|
|
153
|
+
|
|
154
154
|
switch type {
|
|
155
155
|
case .began:
|
|
156
156
|
NSLog("Audio session interruption began")
|
|
157
157
|
audioDevice.isEnabled = false
|
|
158
158
|
notifyListeners("audioSessionInterrupted", data: ["type": "began"])
|
|
159
|
-
|
|
159
|
+
|
|
160
160
|
case .ended:
|
|
161
161
|
NSLog("Audio session interruption ended")
|
|
162
|
-
|
|
162
|
+
|
|
163
163
|
// Check if we should resume
|
|
164
164
|
if let optionsValue = userInfo[AVAudioSessionInterruptionOptionKey] as? UInt {
|
|
165
165
|
let options = AVAudioSession.InterruptionOptions(rawValue: optionsValue)
|
|
@@ -174,9 +174,9 @@ public class CapacitorTwilioVoicePlugin: CAPPlugin, CAPBridgedPlugin, PushKitEve
|
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
|
-
|
|
177
|
+
|
|
178
178
|
notifyListeners("audioSessionInterrupted", data: ["type": "ended"])
|
|
179
|
-
|
|
179
|
+
|
|
180
180
|
@unknown default:
|
|
181
181
|
break
|
|
182
182
|
}
|
|
@@ -574,37 +574,37 @@ public class CapacitorTwilioVoicePlugin: CAPPlugin, CAPBridgedPlugin, PushKitEve
|
|
|
574
574
|
audioDevice.block = {
|
|
575
575
|
do {
|
|
576
576
|
let audioSession = AVAudioSession.sharedInstance()
|
|
577
|
-
|
|
577
|
+
|
|
578
578
|
// Ensure audio session is active before changing routing
|
|
579
579
|
if !audioSession.isOtherAudioPlaying {
|
|
580
580
|
try audioSession.setActive(true)
|
|
581
581
|
}
|
|
582
|
-
|
|
582
|
+
|
|
583
583
|
if toSpeaker {
|
|
584
584
|
try audioSession.overrideOutputAudioPort(.speaker)
|
|
585
585
|
} else {
|
|
586
586
|
try audioSession.overrideOutputAudioPort(.none)
|
|
587
587
|
}
|
|
588
|
-
|
|
588
|
+
|
|
589
589
|
NSLog("Audio route changed to: \(toSpeaker ? "speaker" : "earpiece")")
|
|
590
590
|
} catch {
|
|
591
591
|
NSLog("Failed to change audio route: \(error.localizedDescription)")
|
|
592
|
-
|
|
592
|
+
|
|
593
593
|
// Try to recover by reconfiguring the audio session
|
|
594
594
|
do {
|
|
595
595
|
let audioSession = AVAudioSession.sharedInstance()
|
|
596
|
-
try audioSession.setCategory(.playAndRecord,
|
|
597
|
-
|
|
598
|
-
|
|
596
|
+
try audioSession.setCategory(.playAndRecord,
|
|
597
|
+
mode: .voiceChat,
|
|
598
|
+
options: [.allowBluetooth, .allowBluetoothA2DP, .allowAirPlay])
|
|
599
599
|
try audioSession.setActive(true)
|
|
600
|
-
|
|
600
|
+
|
|
601
601
|
// Retry the audio route change
|
|
602
602
|
if toSpeaker {
|
|
603
603
|
try audioSession.overrideOutputAudioPort(.speaker)
|
|
604
604
|
} else {
|
|
605
605
|
try audioSession.overrideOutputAudioPort(.none)
|
|
606
606
|
}
|
|
607
|
-
|
|
607
|
+
|
|
608
608
|
NSLog("Audio route recovered and changed to: \(toSpeaker ? "speaker" : "earpiece")")
|
|
609
609
|
} catch {
|
|
610
610
|
NSLog("Failed to recover audio route: \(error.localizedDescription)")
|
|
@@ -965,12 +965,12 @@ extension CapacitorTwilioVoicePlugin: CXProviderDelegate {
|
|
|
965
965
|
|
|
966
966
|
public func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) {
|
|
967
967
|
NSLog("CallKit activated audio session")
|
|
968
|
-
|
|
968
|
+
|
|
969
969
|
// Configure the audio session for VoIP calls
|
|
970
970
|
do {
|
|
971
|
-
try audioSession.setCategory(.playAndRecord,
|
|
972
|
-
|
|
973
|
-
|
|
971
|
+
try audioSession.setCategory(.playAndRecord,
|
|
972
|
+
mode: .voiceChat,
|
|
973
|
+
options: [.allowBluetooth, .allowBluetoothA2DP, .allowAirPlay])
|
|
974
974
|
audioDevice.isEnabled = true
|
|
975
975
|
NSLog("Audio session activated and configured for call")
|
|
976
976
|
} catch {
|