pushwoosh-cordova-plugin 8.3.50 → 8.3.51

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 (30) hide show
  1. package/README.md +2 -2
  2. package/example_voip/LICENSE +21 -0
  3. package/example_voip/README.md +157 -0
  4. package/example_voip/Screenshots/Android.png +0 -0
  5. package/example_voip/Screenshots/iOS.png +0 -0
  6. package/example_voip/Screenshots/xcode_appgroups.png +0 -0
  7. package/example_voip/demovoip/README.md +182 -0
  8. package/example_voip/demovoip/config.xml +22 -0
  9. package/example_voip/demovoip/google-services.json +86 -0
  10. package/example_voip/demovoip/hooks/after_platform_add/010_install_plugin.js +46 -0
  11. package/example_voip/demovoip/hooks/after_prepare/010_setup_gradle_wrapper.js +34 -0
  12. package/example_voip/demovoip/hooks/after_prepare/015_fix_agp_version.js +36 -0
  13. package/example_voip/demovoip/hooks/after_prepare/020_copy_google_services.js +23 -0
  14. package/example_voip/demovoip/hooks/after_prepare/025_add_voip_pod.js +43 -0
  15. package/example_voip/demovoip/hooks/after_prepare.js +28 -0
  16. package/example_voip/demovoip/package-lock.json +1324 -0
  17. package/example_voip/demovoip/package.json +34 -0
  18. package/example_voip/demovoip/www/css/index.css +605 -0
  19. package/example_voip/demovoip/www/img/logo.png +0 -0
  20. package/example_voip/demovoip/www/index.html +159 -0
  21. package/example_voip/demovoip/www/js/index.js +309 -0
  22. package/package.json +1 -1
  23. package/plugin.xml +10 -10
  24. package/src/android/add-android-voip.gradle +1 -1
  25. package/src/android/src/com/pushwoosh/plugin/pushnotifications/PushNotifications.java +2 -0
  26. package/src/android/src/com/pushwoosh/plugin/pushnotifications/calls/PWCordovaCallEventListener.java +31 -1
  27. package/src/android/src/com/pushwoosh/plugin/pushnotifications/calls/PushwooshCallsAdapter.java +20 -2
  28. package/src/ios/PWLog.h +11 -17
  29. package/src/ios/PushNotification.m +36 -5
  30. package/www/PushNotification.js +4 -0
@@ -0,0 +1,159 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">
6
+ <meta name="format-detection" content="telephone=no">
7
+ <meta name="msapplication-tap-highlight" content="no">
8
+ <meta name="viewport" content="initial-scale=1, width=device-width, viewport-fit=cover">
9
+ <meta name="color-scheme" content="light dark">
10
+ <link rel="stylesheet" href="css/index.css">
11
+ <title>Pushwoosh VoIP Demo</title>
12
+ </head>
13
+ <body>
14
+ <!-- Welcome Screen -->
15
+ <div id="welcomeScreen" class="welcome-overlay">
16
+ <div class="welcome-content">
17
+ <h2>Welcome to Pushwoosh VoIP Demo</h2>
18
+ <div class="welcome-instructions">
19
+ <p><strong>How to use this app:</strong></p>
20
+ <ol>
21
+ <li>Enter your App ID (VoIP App Code) and FCM Project ID</li>
22
+ <li>Click "Initialize Pushwoosh" to start the SDK</li>
23
+ <li>Initialize VoIP Parameters to configure video support and ringtone</li>
24
+ <li>Request Call Permission on Android if needed</li>
25
+ <li>Use End Call button to terminate active calls</li>
26
+ <li>Monitor VoIP events in the Event Log below</li>
27
+ </ol>
28
+ <p><strong>Testing VoIP Calls:</strong></p>
29
+ <p>To receive incoming VoIP calls, send a VoIP push notification from the Pushwoosh Control Panel using your App ID.</p>
30
+ </div>
31
+ <div class="welcome-footer">
32
+ <label class="welcome-checkbox">
33
+ <input type="checkbox" id="dontShowAgain">
34
+ <span>Don't show this again</span>
35
+ </label>
36
+ <button id="btnGetStarted" class="btn btn-primary">Get Started</button>
37
+ </div>
38
+ </div>
39
+ </div>
40
+
41
+ <!-- Cancelled Call Modal -->
42
+ <div id="cancelledCallModal" class="call-modal hidden">
43
+ <div class="call-modal-content">
44
+ <div class="call-modal-icon">📞</div>
45
+ <h2>Call Cancelled</h2>
46
+ <p class="call-modal-subtitle">The caller has ended the call</p>
47
+ <div class="call-details">
48
+ <div class="call-detail-item">
49
+ <span class="call-detail-label">Caller:</span>
50
+ <span id="cancelledCallerName" class="call-detail-value">Unknown</span>
51
+ </div>
52
+ <div class="call-detail-item">
53
+ <span class="call-detail-label">Call ID:</span>
54
+ <span id="cancelledCallId" class="call-detail-value">N/A</span>
55
+ </div>
56
+ <div class="call-detail-item">
57
+ <span class="call-detail-label">Handle Type:</span>
58
+ <span id="cancelledHandleType" class="call-detail-value">N/A</span>
59
+ </div>
60
+ <div class="call-detail-item">
61
+ <span class="call-detail-label">Video:</span>
62
+ <span id="cancelledHasVideo" class="call-detail-value">No</span>
63
+ </div>
64
+ </div>
65
+ <button id="btnDismissCancelledCall" class="btn btn-primary">OK</button>
66
+ </div>
67
+ </div>
68
+
69
+ <div class="app">
70
+ <div class="scroll-content">
71
+ <!-- Device Status -->
72
+ <div id="deviceready" class="status-indicator">
73
+ <div class="status listening">Connecting to Device...</div>
74
+ <div class="status ready">Device Ready</div>
75
+ </div>
76
+
77
+ <!-- Push Notifications Setup Section -->
78
+ <div class="section">
79
+ <h2>Push Notifications Setup</h2>
80
+
81
+ <div class="form-group">
82
+ <label for="pushAppId">App ID / VoIP App Code</label>
83
+ <input type="text" id="pushAppId" value="7BCDB-76CBE">
84
+ </div>
85
+
86
+ <div class="form-group">
87
+ <label for="pushProjectId">FCM Project ID (Android)</label>
88
+ <input type="text" id="pushProjectId" value="843884467752">
89
+ </div>
90
+
91
+ <button id="btnInitPushwoosh" class="btn btn-primary">Initialize Pushwoosh</button>
92
+ </div>
93
+
94
+ <!-- VoIP Parameters Section -->
95
+ <div class="section">
96
+ <h2>VoIP Parameters</h2>
97
+
98
+ <div class="form-group">
99
+ <label class="checkbox-label">
100
+ <input type="checkbox" id="supportsVideo" checked>
101
+ <span>Supports Video</span>
102
+ </label>
103
+ </div>
104
+
105
+ <div class="form-group">
106
+ <label for="ringtoneSound">Ringtone Sound</label>
107
+ <input type="text" id="ringtoneSound" value="ring.caf" placeholder="ring.caf">
108
+ </div>
109
+
110
+ <div class="form-group">
111
+ <label for="handleType">Handle Type</label>
112
+ <select id="handleType">
113
+ <option value="1">Generic - Generic handle type</option>
114
+ <option value="2" selected>Phone Number - Phone number handle</option>
115
+ <option value="3">Email Address - Email address handle</option>
116
+ </select>
117
+ </div>
118
+
119
+ <button id="btnInitVoIP" class="btn btn-primary">Initialize VoIP Parameters</button>
120
+ </div>
121
+
122
+ <!-- Call Permissions Section -->
123
+ <div class="section">
124
+ <h2>Call Permissions</h2>
125
+ <button id="btnRequestCallPermission" class="btn btn-secondary">
126
+ Request Call Permission (Android Only)
127
+ </button>
128
+ <button id="btnGetCallPermissionStatus" class="btn btn-secondary">
129
+ Get Call Permission Status
130
+ </button>
131
+ <div id="permissionStatus" class="status-text"></div>
132
+ </div>
133
+
134
+ <!-- Push Notifications Registration Section -->
135
+ <div class="section">
136
+ <h2>Push Notifications</h2>
137
+ <button id="btnRegisterPush" class="btn btn-secondary">
138
+ Register for Push Notifications (Android Only)
139
+ </button>
140
+ </div>
141
+
142
+ <!-- Call Controls Section -->
143
+ <div class="section">
144
+ <h2>Call Controls</h2>
145
+ <button id="btnEndCall" class="btn btn-danger">End Call</button>
146
+ </div>
147
+
148
+ <!-- VoIP Events Log Section -->
149
+ <div class="section">
150
+ <h2>VoIP Events Log</h2>
151
+ <button id="btnClearLog" class="btn btn-small">Clear Log</button>
152
+ <div id="eventLog" class="event-log"></div>
153
+ </div>
154
+ </div>
155
+ </div>
156
+ <script src="cordova.js"></script>
157
+ <script src="js/index.js"></script>
158
+ </body>
159
+ </html>
@@ -0,0 +1,309 @@
1
+ /*
2
+ * Licensed to the Apache Software Foundation (ASF) under one
3
+ * or more contributor license agreements. See the NOTICE file
4
+ * distributed with this work for additional information
5
+ * regarding copyright ownership. The ASF licenses this file
6
+ * to you under the Apache License, Version 2.0 (the
7
+ * "License"); you may not use this file except in compliance
8
+ * with the License. You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing,
13
+ * software distributed under the License is distributed on an
14
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ * KIND, either express or implied. See the License for the
16
+ * specific language governing permissions and limitations
17
+ * under the License.
18
+ */
19
+
20
+ document.addEventListener('deviceready', onDeviceReady, false);
21
+
22
+ document.addEventListener('DOMContentLoaded', function() {
23
+ checkAndShowWelcomeScreen();
24
+ setupUIEventListeners();
25
+ setupWelcomeScreen();
26
+ });
27
+
28
+ let pushwoosh = null;
29
+
30
+ function checkAndShowWelcomeScreen() {
31
+ const dontShowAgain = localStorage.getItem('dontShowWelcome');
32
+ const welcomeScreen = document.getElementById('welcomeScreen');
33
+
34
+ if (dontShowAgain === 'true') {
35
+ welcomeScreen.classList.add('hidden');
36
+ } else {
37
+ welcomeScreen.classList.remove('hidden');
38
+ }
39
+ }
40
+
41
+ function setupWelcomeScreen() {
42
+ document.getElementById('btnGetStarted').addEventListener('click', function() {
43
+ const dontShowCheckbox = document.getElementById('dontShowAgain');
44
+
45
+ if (dontShowCheckbox.checked) {
46
+ localStorage.setItem('dontShowWelcome', 'true');
47
+ }
48
+
49
+ document.getElementById('welcomeScreen').classList.add('hidden');
50
+ });
51
+ }
52
+
53
+ // VoIP event names
54
+ const VOIP_EVENTS = [
55
+ 'voipPushPayload',
56
+ 'answer',
57
+ 'reject',
58
+ 'hangup',
59
+ 'muted',
60
+ 'unmuted',
61
+ 'held',
62
+ 'unheld',
63
+ 'dtmf',
64
+ 'audioInterruption',
65
+ 'callFailed',
66
+ 'providerDidActivate',
67
+ 'providerDidDeactivate',
68
+ 'incomingCallSuccess',
69
+ 'incomingCallFailure',
70
+ 'playDTMF',
71
+ 'voipDidFailToRegisterTokenWithError',
72
+ 'voipDidRegisterTokenSuccessfully',
73
+ 'voipDidCancelCall',
74
+ 'voipDidFailToCancelCall'
75
+ ];
76
+
77
+ function onDeviceReady() {
78
+ console.log('Running cordova-' + cordova.platformId + '@' + cordova.version);
79
+ document.getElementById('deviceready').classList.add('ready');
80
+
81
+ pushwoosh = cordova.require("pushwoosh-cordova-plugin.PushNotification");
82
+
83
+ registerVoIPEvents();
84
+
85
+ // Auto-initialize with default values
86
+ const appId = document.getElementById('pushAppId').value;
87
+ const projectId = document.getElementById('pushProjectId').value;
88
+ if (appId) {
89
+ initializePushwoosh(appId, projectId);
90
+ }
91
+ }
92
+
93
+ function initializePushwoosh(appId, projectId) {
94
+ console.log('Initializing Pushwoosh with App ID:', appId, 'Project ID:', projectId);
95
+
96
+ // Set VoIP App Code
97
+ pushwoosh.setVoipAppCode(appId);
98
+ console.log('VoIP App Code set to:', appId);
99
+
100
+ // Initialize Pushwoosh
101
+ pushwoosh.onDeviceReady({
102
+ "appid": appId,
103
+ "projectid": projectId || ""
104
+ });
105
+
106
+ pushwoosh.getPushToken(
107
+ function(token) {
108
+ console.log('Push Token:', token);
109
+ }
110
+ );
111
+
112
+ pushwoosh.getPushwooshHWID(
113
+ function(hwid) {
114
+ console.log('HWID:', hwid);
115
+ }
116
+ );
117
+ }
118
+
119
+ function registerVoIPEvents() {
120
+ VOIP_EVENTS.forEach(function(eventName) {
121
+ pushwoosh.registerEvent(
122
+ eventName,
123
+ function(data) {
124
+ console.log('[VoIP Event] ' + eventName + ':', data);
125
+ logEventToUI(eventName, JSON.stringify(data, null, 2));
126
+
127
+ // Special handling for call cancellation
128
+ if (eventName === 'voipDidCancelCall') {
129
+ showCancelledCallModal(data);
130
+ }
131
+ },
132
+ function(error) {
133
+ console.error('Failed to register event ' + eventName + ':', error);
134
+ }
135
+ );
136
+ });
137
+ }
138
+
139
+ function setupUIEventListeners() {
140
+ // Initialize Pushwoosh button
141
+ document.getElementById('btnInitPushwoosh').addEventListener('click', function() {
142
+ const appId = document.getElementById('pushAppId').value;
143
+ const projectId = document.getElementById('pushProjectId').value;
144
+
145
+ if (!appId) {
146
+ alert('Please enter App ID');
147
+ return;
148
+ }
149
+
150
+ if (!pushwoosh) {
151
+ alert('Pushwoosh not initialized yet. Wait for device ready.');
152
+ return;
153
+ }
154
+
155
+ initializePushwoosh(appId, projectId);
156
+ });
157
+
158
+ // Initialize VoIP Parameters button
159
+ document.getElementById('btnInitVoIP').addEventListener('click', function() {
160
+ if (!pushwoosh) {
161
+ alert('Pushwoosh not initialized yet. Wait for device ready.');
162
+ return;
163
+ }
164
+ initializeVoIPParameters();
165
+ });
166
+
167
+ // Request Call Permission button (Android only)
168
+ document.getElementById('btnRequestCallPermission').addEventListener('click', function() {
169
+ if (!pushwoosh) {
170
+ alert('Pushwoosh not initialized yet. Wait for device ready.');
171
+ return;
172
+ }
173
+ pushwoosh.requestCallPermission();
174
+ console.log('Call permission requested (Android only)');
175
+ });
176
+
177
+ // Get Call Permission Status button
178
+ document.getElementById('btnGetCallPermissionStatus').addEventListener('click', function() {
179
+ if (!pushwoosh) {
180
+ alert('Pushwoosh not initialized yet. Wait for device ready.');
181
+ return;
182
+ }
183
+ pushwoosh.getCallPermissionStatus(
184
+ function(status) {
185
+ const statusText = 'Call Permission Status: ' + (status ? 'Granted' : 'Denied');
186
+ document.getElementById('permissionStatus').textContent = statusText;
187
+ console.log(statusText);
188
+ },
189
+ function(error) {
190
+ const errorText = 'Error getting permission status: ' + error;
191
+ document.getElementById('permissionStatus').textContent = errorText;
192
+ console.log(errorText);
193
+ }
194
+ );
195
+ });
196
+
197
+ // Register for Push Notifications button (Android only)
198
+ document.getElementById('btnRegisterPush').addEventListener('click', function() {
199
+ if (!pushwoosh) {
200
+ alert('Pushwoosh not initialized yet. Wait for device ready.');
201
+ return;
202
+ }
203
+ pushwoosh.registerDevice(
204
+ function(status) {
205
+ var pushToken = status.pushToken;
206
+ console.log('Push token received:', pushToken);
207
+ alert('Successfully registered! Push token: ' + pushToken);
208
+ },
209
+ function(status) {
210
+ console.log('Failed to register for push:', status);
211
+ alert('Failed to register for push notifications: ' + status);
212
+ }
213
+ );
214
+ });
215
+
216
+ // End Call button
217
+ document.getElementById('btnEndCall').addEventListener('click', function() {
218
+ if (!pushwoosh) {
219
+ alert('Pushwoosh not initialized yet. Wait for device ready.');
220
+ return;
221
+ }
222
+ pushwoosh.endCall(
223
+ function() {
224
+ console.log('Call ended successfully');
225
+ },
226
+ function(error) {
227
+ console.log('Failed to end call: ' + error);
228
+ }
229
+ );
230
+ });
231
+
232
+ // Clear Log button
233
+ document.getElementById('btnClearLog').addEventListener('click', function() {
234
+ document.getElementById('eventLog').innerHTML = '';
235
+ });
236
+ }
237
+
238
+ function initializeVoIPParameters() {
239
+ const supportsVideo = document.getElementById('supportsVideo').checked;
240
+ const ringtoneSound = document.getElementById('ringtoneSound').value;
241
+ const handleType = parseInt(document.getElementById('handleType').value);
242
+
243
+ console.log('Initializing VoIP with parameters:', {
244
+ supportsVideo: supportsVideo,
245
+ ringtoneSound: ringtoneSound,
246
+ handleType: handleType
247
+ });
248
+
249
+ pushwoosh.initializeVoIPParameters(
250
+ supportsVideo,
251
+ ringtoneSound,
252
+ handleType,
253
+ function() {
254
+ console.log('VoIP parameters initialized successfully');
255
+ },
256
+ function(error) {
257
+ console.log('Failed to initialize VoIP parameters:', error);
258
+ }
259
+ );
260
+ }
261
+
262
+ function logEventToUI(eventName, data) {
263
+ const timestamp = new Date().toLocaleTimeString();
264
+
265
+ const eventLog = document.getElementById('eventLog');
266
+ const logEntry = document.createElement('div');
267
+ logEntry.className = 'log-entry';
268
+
269
+ logEntry.innerHTML =
270
+ '<span class="timestamp">[' + timestamp + ']</span>' +
271
+ '<span class="event-name">' + eventName + '</span>' +
272
+ '<br/>' +
273
+ '<span class="event-data">' + (data || '') + '</span>';
274
+
275
+ eventLog.insertBefore(logEntry, eventLog.firstChild);
276
+
277
+ while (eventLog.children.length > 50) {
278
+ eventLog.removeChild(eventLog.lastChild);
279
+ }
280
+ }
281
+
282
+ function showCancelledCallModal(voipMessage) {
283
+ const modal = document.getElementById('cancelledCallModal');
284
+
285
+ // Map handle type to readable text
286
+ const handleTypeMap = {
287
+ 1: 'Generic',
288
+ 2: 'Phone Number',
289
+ 3: 'Email Address'
290
+ };
291
+
292
+ // Update modal content with call data
293
+ document.getElementById('cancelledCallerName').textContent = voipMessage.callerName || 'Unknown';
294
+ document.getElementById('cancelledCallId').textContent = voipMessage.callId || 'N/A';
295
+ document.getElementById('cancelledHandleType').textContent = handleTypeMap[voipMessage.handleType] || 'Unknown';
296
+ document.getElementById('cancelledHasVideo').textContent = voipMessage.hasVideo ? 'Yes' : 'No';
297
+
298
+ // Show modal
299
+ modal.classList.remove('hidden');
300
+
301
+ // Setup dismiss button if not already done
302
+ const dismissBtn = document.getElementById('btnDismissCancelledCall');
303
+ if (!dismissBtn.hasListener) {
304
+ dismissBtn.addEventListener('click', function() {
305
+ modal.classList.add('hidden');
306
+ });
307
+ dismissBtn.hasListener = true;
308
+ }
309
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pushwoosh-cordova-plugin",
3
- "version": "8.3.50",
3
+ "version": "8.3.51",
4
4
  "description": "\n This plugin allows you to send and receive push notifications. Powered by Pushwoosh (www.pushwoosh.com).\n ",
5
5
  "main":"www/PushNotification.js",
6
6
  "typings":"types/index.d.ts",
package/plugin.xml CHANGED
@@ -1,5 +1,5 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android" id="pushwoosh-cordova-plugin" version="8.3.50">
2
+ <plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android" id="pushwoosh-cordova-plugin" version="8.3.51">
3
3
 
4
4
  <name>Pushwoosh</name>
5
5
 
@@ -95,13 +95,13 @@
95
95
  <framework src="org.jetbrains.kotlin:kotlin-stdlib:1.1.60" />
96
96
  <framework src="com.google.android.material:material:1.12.0"/>
97
97
 
98
- <framework src="com.pushwoosh:pushwoosh:6.7.44"/>
99
- <framework src="com.pushwoosh:pushwoosh-amazon:6.7.44"/>
100
- <framework src="com.pushwoosh:pushwoosh-firebase:6.7.44"/>
101
- <framework src="com.pushwoosh:pushwoosh-badge:6.7.44"/>
102
- <framework src="com.pushwoosh:pushwoosh-inbox:6.7.44"/>
103
- <framework src="com.pushwoosh:pushwoosh-inbox-ui:6.7.44"/>
104
- <framework src="com.pushwoosh:pushwoosh-huawei:6.7.44"/>
98
+ <framework src="com.pushwoosh:pushwoosh:6.7.45"/>
99
+ <framework src="com.pushwoosh:pushwoosh-amazon:6.7.45"/>
100
+ <framework src="com.pushwoosh:pushwoosh-firebase:6.7.45"/>
101
+ <framework src="com.pushwoosh:pushwoosh-badge:6.7.45"/>
102
+ <framework src="com.pushwoosh:pushwoosh-inbox:6.7.45"/>
103
+ <framework src="com.pushwoosh:pushwoosh-inbox-ui:6.7.45"/>
104
+ <framework src="com.pushwoosh:pushwoosh-huawei:6.7.45"/>
105
105
  </platform>
106
106
 
107
107
  <!-- ios -->
@@ -143,8 +143,8 @@
143
143
  <source url="https://github.com/CocoaPods/Specs.git"/>
144
144
  </config>
145
145
  <pods use-frameworks="true">
146
- <pod name="PushwooshXCFramework" spec="6.11.3" />
147
- <pod name="PushwooshInboxUIXCFramework" spec="6.1.2" />
146
+ <pod name="PushwooshXCFramework" spec="7.0.2" />
147
+ <pod name="PushwooshInboxUIXCFramework" spec="7.0.2" />
148
148
  </pods>
149
149
  </podspec>
150
150
 
@@ -16,7 +16,7 @@ def callsSrc = pluginDir ? new File(pluginDir, 'src/android/src/com/pushwoosh/pl
16
16
  def applyVoip = {
17
17
  if (voipEnabled) {
18
18
  println "[${pluginId}] PW_VOIP_ANDROID_ENABLED=true — enabling VoIP (dependency + sources)"
19
- dependencies { implementation "com.pushwoosh:pushwoosh-calls:6.7.44" }
19
+ dependencies { implementation "com.pushwoosh:pushwoosh-calls:6.7.45" }
20
20
  if (callsSrc?.exists()) {
21
21
  android.sourceSets.main.java.srcDirs += callsSrc
22
22
  println "[${pluginId}] Added optional sources: ${callsSrc}"
@@ -864,6 +864,8 @@ public class PushNotifications extends CordovaPlugin {
864
864
  callbackContextMap.put("reject", new ArrayList<CallbackContext>());
865
865
  callbackContextMap.put("hangup", new ArrayList<CallbackContext>());
866
866
  callbackContextMap.put("voipPushPayload", new ArrayList<CallbackContext>());
867
+ callbackContextMap.put("voipDidCancelCall", new ArrayList<CallbackContext>());
868
+ callbackContextMap.put("voipDidFailToCancelCall", new ArrayList<CallbackContext>());
867
869
  }
868
870
 
869
871
  @Override
@@ -1,5 +1,7 @@
1
1
  package com.pushwoosh.plugin.pushnotifications.calls;
2
2
 
3
+ import android.content.Context;
4
+ import android.content.Intent;
3
5
  import android.os.Bundle;
4
6
 
5
7
  import androidx.annotation.NonNull;
@@ -7,7 +9,8 @@ import androidx.annotation.Nullable;
7
9
 
8
10
  import com.pushwoosh.calls.PushwooshVoIPMessage;
9
11
  import com.pushwoosh.calls.listener.CallEventListener;
10
- import com.pushwoosh.plugin.pushnotifications.PushNotifications;
12
+ import com.pushwoosh.internal.platform.AndroidPlatformModule;
13
+ import com.pushwoosh.internal.utils.PWLog;
11
14
 
12
15
  public class PWCordovaCallEventListener implements CallEventListener {
13
16
  private static final Object sCurrentCallLock = new Object();
@@ -19,6 +22,20 @@ public class PWCordovaCallEventListener implements CallEventListener {
19
22
  synchronized (sCurrentCallLock) {
20
23
  currentCallInfo = pushwooshVoIPMessage.getRawPayload();
21
24
  }
25
+
26
+ try {
27
+ Context context = AndroidPlatformModule.getApplicationContext();
28
+ Intent launchIntent = context != null ? context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()) : null;
29
+
30
+ if (launchIntent != null) {
31
+ launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
32
+ context.startActivity(launchIntent);
33
+ PWLog.info("PWCordovaCallEventListener", "Launched main activity for call");
34
+ }
35
+ } catch (Exception e) {
36
+ PWLog.error("PWCordovaCallEventListener", "Failed to launch activity", e);
37
+ }
38
+
22
39
  PushwooshCallsAdapter.onAnswer(pushwooshVoIPMessage);
23
40
  }
24
41
 
@@ -56,6 +73,19 @@ public class PWCordovaCallEventListener implements CallEventListener {
56
73
  //stub
57
74
  }
58
75
 
76
+ @Override
77
+ public void onCallCancelled(@NonNull PushwooshVoIPMessage pushwooshVoIPMessage) {
78
+ PushwooshCallsAdapter.onCallCancelled(pushwooshVoIPMessage);
79
+ synchronized (sCurrentCallLock) {
80
+ currentCallInfo = null;
81
+ }
82
+ }
83
+
84
+ @Override
85
+ public void onCallCancellationFailed(@Nullable String callId, @Nullable String reason) {
86
+ PushwooshCallsAdapter.onCallCancellationFailed(callId, reason);
87
+ }
88
+
59
89
  public static Bundle getCurrentCallInfo() {
60
90
  synchronized (sCurrentCallLock) {
61
91
  return currentCallInfo;
@@ -180,20 +180,38 @@ public class PushwooshCallsAdapter implements CallsAdapter {
180
180
  PushNotifications.emitVoipEvent("hangup", parseVoIPMessage(voIPMessage));
181
181
  }
182
182
 
183
- public static void onCreateIncomingConnection(Bundle bundle) {
183
+ public static void onCreateIncomingConnection(Bundle bundle) {
184
184
  PushwooshVoIPMessage voipMessage = new PushwooshVoIPMessage(bundle);
185
185
  PushNotifications.emitVoipEvent("voipPushPayload", parseVoIPMessage(voipMessage));
186
186
  }
187
187
 
188
+ public static void onCallCancelled(PushwooshVoIPMessage voIPMessage) {
189
+ PushNotifications.emitVoipEvent("voipDidCancelCall", parseVoIPMessage(voIPMessage));
190
+ }
191
+
192
+ public static void onCallCancellationFailed(String callId, String reason) {
193
+ org.json.JSONObject payload = new org.json.JSONObject();
194
+ try {
195
+ payload.put("callId", callId != null ? callId : "");
196
+ payload.put("reason", reason != null ? reason : "");
197
+ } catch (org.json.JSONException ignored) {}
198
+ PushNotifications.emitVoipEvent("voipDidFailToCancelCall", payload);
199
+ }
200
+
188
201
  private static org.json.JSONObject parseVoIPMessage(PushwooshVoIPMessage message) {
189
202
  org.json.JSONObject payload = new org.json.JSONObject();
190
203
  try {
191
204
  Bundle rawBundle = message.getRawPayload();
192
205
  org.json.JSONObject rawPayloadJson = JsonUtils.bundleToJsonWithUserData(rawBundle);
193
-
206
+
194
207
  payload.put("callerName", message.getCallerName())
208
+ .put("callId", message.getCallId())
195
209
  .put("rawPayload", rawPayloadJson)
196
210
  .put("hasVideo", message.getHasVideo());
211
+
212
+ if (rawBundle != null && rawBundle.containsKey("handleType")) {
213
+ payload.put("handleType", rawBundle.get("handleType"));
214
+ }
197
215
  } catch (org.json.JSONException ignored) {}
198
216
  return payload;
199
217
  }
package/src/ios/PWLog.h CHANGED
@@ -1,25 +1,19 @@
1
1
  //
2
2
  // PWLog.h
3
3
  // Pushwoosh SDK
4
- // (c) Pushwoosh 2016
4
+ // (c) Pushwoosh 2025
5
5
  //
6
+ // Using PushwooshCore logging
6
7
 
7
8
  #import <Foundation/Foundation.h>
8
9
 
9
- typedef NS_ENUM(unsigned int, LogLevel) {
10
- kLogNone = 0,
11
- kLogError,
12
- kLogWarning,
13
- kLogInfo,
14
- kLogDebug,
15
- kLogVerbose
16
- };
10
+ // Logging macros using NSLog
11
+ #define PWLog(fmt, ...) NSLog(@"[Pushwoosh] %s: " fmt, __FUNCTION__, ##__VA_ARGS__)
12
+ #define PWLogError(fmt, ...) NSLog(@"[Pushwoosh ERROR] %s: " fmt, __FUNCTION__, ##__VA_ARGS__)
13
+ #define PWLogWarn(fmt, ...) NSLog(@"[Pushwoosh WARN] %s: " fmt, __FUNCTION__, ##__VA_ARGS__)
14
+ #define PWLogInfo(fmt, ...) NSLog(@"[Pushwoosh INFO] %s: " fmt, __FUNCTION__, ##__VA_ARGS__)
15
+ #define PWLogDebug(fmt, ...) NSLog(@"[Pushwoosh DEBUG] %s: " fmt, __FUNCTION__, ##__VA_ARGS__)
16
+ #define PWLogVerbose(fmt, ...) NSLog(@"[Pushwoosh VERBOSE] %s: " fmt, __FUNCTION__, ##__VA_ARGS__)
17
17
 
18
- #define PWLog(...) PWLogInternal(__FUNCTION__, kLogInfo, __VA_ARGS__)
19
- #define PWLogError(...) PWLogInternal(__FUNCTION__, kLogError, __VA_ARGS__)
20
- #define PWLogWarn(...) PWLogInternal(__FUNCTION__, kLogWarning, __VA_ARGS__)
21
- #define PWLogInfo(...) PWLogInternal(__FUNCTION__, kLogInfo, __VA_ARGS__)
22
- #define PWLogDebug(...) PWLogInternal(__FUNCTION__, kLogDebug, __VA_ARGS__)
23
- #define PWLogVerbose(...) PWLogInternal(__FUNCTION__, kLogVerbose, __VA_ARGS__)
24
-
25
- void PWLogInternal(const char *function, LogLevel logLevel, NSString *format, ...);
18
+ // Backward compatibility
19
+ #define PWLogInternal(func, level, fmt, ...) NSLog(@"[Pushwoosh] %s: " fmt, func, ##__VA_ARGS__)