pushwoosh-cordova-plugin 8.3.55 → 8.3.56
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/README.md +2 -2
- package/package.json +1 -1
- package/plugin.xml +12 -9
- package/src/android/add-android-voip.gradle +1 -1
- package/src/android/src/com/pushwoosh/plugin/pushnotifications/PushNotifications.java +123 -37
- package/src/android/src/com/pushwoosh/plugin/pushnotifications/VoIPEventStorage.java +130 -0
- package/src/android/src/com/pushwoosh/plugin/pushnotifications/calls/PWCordovaCallEventListener.java +61 -34
- package/src/android/src/com/pushwoosh/plugin/pushnotifications/calls/PushwooshCallsAdapter.java +19 -0
package/README.md
CHANGED
|
@@ -14,13 +14,13 @@ Cross-Platform push notifications by Pushwoosh for Cordova / PhoneGap
|
|
|
14
14
|
Using npm:
|
|
15
15
|
|
|
16
16
|
```
|
|
17
|
-
cordova plugin add pushwoosh-cordova-plugin@8.3.
|
|
17
|
+
cordova plugin add pushwoosh-cordova-plugin@8.3.56
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
Using git:
|
|
21
21
|
|
|
22
22
|
```
|
|
23
|
-
cordova plugin add https://github.com/Pushwoosh/pushwoosh-phonegap-plugin.git#8.3.
|
|
23
|
+
cordova plugin add https://github.com/Pushwoosh/pushwoosh-phonegap-plugin.git#8.3.56
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
### Guide
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pushwoosh-cordova-plugin",
|
|
3
|
-
"version": "8.3.
|
|
3
|
+
"version": "8.3.56",
|
|
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.
|
|
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.56">
|
|
3
3
|
|
|
4
4
|
<name>Pushwoosh</name>
|
|
5
5
|
|
|
@@ -65,6 +65,9 @@
|
|
|
65
65
|
<source-file src="src/android/src/com/pushwoosh/plugin/pushnotifications/InboxUiStyleManager.java"
|
|
66
66
|
target-dir="src/com/pushwoosh/plugin/pushnotifications" />
|
|
67
67
|
|
|
68
|
+
<source-file src="src/android/src/com/pushwoosh/plugin/pushnotifications/VoIPEventStorage.java"
|
|
69
|
+
target-dir="src/com/pushwoosh/plugin/pushnotifications" />
|
|
70
|
+
|
|
68
71
|
<source-file src="src/android/src/com/pushwoosh/plugin/pushnotifications/PushwooshNotificationServiceExtension.java"
|
|
69
72
|
target-dir="src/com/pushwoosh/plugin/pushnotifications" />
|
|
70
73
|
|
|
@@ -95,13 +98,13 @@
|
|
|
95
98
|
<framework src="org.jetbrains.kotlin:kotlin-stdlib:1.1.60" />
|
|
96
99
|
<framework src="com.google.android.material:material:1.12.0"/>
|
|
97
100
|
|
|
98
|
-
<framework src="com.pushwoosh:pushwoosh:6.7.
|
|
99
|
-
<framework src="com.pushwoosh:pushwoosh-amazon:6.7.
|
|
100
|
-
<framework src="com.pushwoosh:pushwoosh-firebase:6.7.
|
|
101
|
-
<framework src="com.pushwoosh:pushwoosh-badge:6.7.
|
|
102
|
-
<framework src="com.pushwoosh:pushwoosh-inbox:6.7.
|
|
103
|
-
<framework src="com.pushwoosh:pushwoosh-inbox-ui:6.7.
|
|
104
|
-
<framework src="com.pushwoosh:pushwoosh-huawei:6.7.
|
|
101
|
+
<framework src="com.pushwoosh:pushwoosh:6.7.48"/>
|
|
102
|
+
<framework src="com.pushwoosh:pushwoosh-amazon:6.7.48"/>
|
|
103
|
+
<framework src="com.pushwoosh:pushwoosh-firebase:6.7.48"/>
|
|
104
|
+
<framework src="com.pushwoosh:pushwoosh-badge:6.7.48"/>
|
|
105
|
+
<framework src="com.pushwoosh:pushwoosh-inbox:6.7.48"/>
|
|
106
|
+
<framework src="com.pushwoosh:pushwoosh-inbox-ui:6.7.48"/>
|
|
107
|
+
<framework src="com.pushwoosh:pushwoosh-huawei:6.7.48"/>
|
|
105
108
|
</platform>
|
|
106
109
|
|
|
107
110
|
<!-- ios -->
|
|
@@ -143,7 +146,7 @@
|
|
|
143
146
|
<source url="https://github.com/CocoaPods/Specs.git"/>
|
|
144
147
|
</config>
|
|
145
148
|
<pods use-frameworks="true">
|
|
146
|
-
<pod name="PushwooshXCFramework" spec="7.0.
|
|
149
|
+
<pod name="PushwooshXCFramework" spec="7.0.6" />
|
|
147
150
|
<pod name="PushwooshInboxUIXCFramework" spec="7.0.3" />
|
|
148
151
|
</pods>
|
|
149
152
|
</podspec>
|
|
@@ -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.
|
|
19
|
+
dependencies { implementation "com.pushwoosh:pushwoosh-calls:6.7.48" }
|
|
20
20
|
if (callsSrc?.exists()) {
|
|
21
21
|
android.sourceSets.main.java.srcDirs += callsSrc
|
|
22
22
|
println "[${pluginId}] Added optional sources: ${callsSrc}"
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
package com.pushwoosh.plugin.pushnotifications;
|
|
12
12
|
|
|
13
|
+
import android.content.Context;
|
|
13
14
|
import android.content.Intent;
|
|
14
15
|
import android.os.Bundle;
|
|
15
16
|
import android.os.Handler;
|
|
@@ -33,6 +34,7 @@ import com.pushwoosh.inbox.data.InboxMessage;
|
|
|
33
34
|
import com.pushwoosh.inbox.exception.InboxMessagesException;
|
|
34
35
|
import com.pushwoosh.inbox.ui.presentation.view.activity.InboxActivity;
|
|
35
36
|
import com.pushwoosh.internal.platform.utils.GeneralUtils;
|
|
37
|
+
import com.pushwoosh.internal.platform.AndroidPlatformModule;
|
|
36
38
|
import com.pushwoosh.internal.utils.JsonUtils;
|
|
37
39
|
import com.pushwoosh.internal.utils.PWLog;
|
|
38
40
|
import com.pushwoosh.notification.LocalNotification;
|
|
@@ -75,7 +77,6 @@ public class PushNotifications extends CordovaPlugin {
|
|
|
75
77
|
private static AtomicBoolean sAppReady = new AtomicBoolean();
|
|
76
78
|
private static PushNotifications sInstance;
|
|
77
79
|
|
|
78
|
-
// private CallbackContext callbackContext;
|
|
79
80
|
private static CordovaInterface cordovaInterface;
|
|
80
81
|
private static CallsAdapter callsAdapter;
|
|
81
82
|
|
|
@@ -108,6 +109,25 @@ public class PushNotifications extends CordovaPlugin {
|
|
|
108
109
|
return cordovaInterface;
|
|
109
110
|
}
|
|
110
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Checks if Cordova WebView is ready to receive events.
|
|
114
|
+
* Returns false if CordovaInterface is null, Activity is null/finishing/destroyed.
|
|
115
|
+
*/
|
|
116
|
+
private static boolean isCordovaReady() {
|
|
117
|
+
if (cordovaInterface == null) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
try {
|
|
121
|
+
android.app.Activity activity = cordovaInterface.getActivity();
|
|
122
|
+
if (activity == null || activity.isFinishing() || activity.isDestroyed()) {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
return true;
|
|
126
|
+
} catch (Exception e) {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
111
131
|
public static HashMap<String, ArrayList<CallbackContext>> getCallbackContextMap() {
|
|
112
132
|
return callbackContextMap;
|
|
113
133
|
}
|
|
@@ -125,11 +145,26 @@ public class PushNotifications extends CordovaPlugin {
|
|
|
125
145
|
|
|
126
146
|
@Override
|
|
127
147
|
public void onDestroy() {
|
|
148
|
+
PWLog.noise(TAG, "onDestroy()");
|
|
149
|
+
|
|
128
150
|
super.onDestroy();
|
|
129
|
-
PWLog.noise("OnDestroy");
|
|
130
151
|
sAppReady.set(false);
|
|
131
152
|
}
|
|
132
153
|
|
|
154
|
+
@Override
|
|
155
|
+
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
|
|
156
|
+
PWLog.noise(TAG, "initialize()");
|
|
157
|
+
|
|
158
|
+
cordovaInterface = cordova;
|
|
159
|
+
callsAdapter = CallsAdapterFactory.create(cordova.getActivity().getApplicationContext());
|
|
160
|
+
callbackContextMap.put("answer", new ArrayList<CallbackContext>());
|
|
161
|
+
callbackContextMap.put("reject", new ArrayList<CallbackContext>());
|
|
162
|
+
callbackContextMap.put("hangup", new ArrayList<CallbackContext>());
|
|
163
|
+
callbackContextMap.put("voipPushPayload", new ArrayList<CallbackContext>());
|
|
164
|
+
callbackContextMap.put("voipDidCancelCall", new ArrayList<CallbackContext>());
|
|
165
|
+
callbackContextMap.put("voipDidFailToCancelCall", new ArrayList<CallbackContext>());
|
|
166
|
+
}
|
|
167
|
+
|
|
133
168
|
private JSONObject getPushFromIntent(Intent intent) {
|
|
134
169
|
if (null == intent) {
|
|
135
170
|
return null;
|
|
@@ -152,6 +187,8 @@ public class PushNotifications extends CordovaPlugin {
|
|
|
152
187
|
|
|
153
188
|
@CordovaMethod
|
|
154
189
|
private boolean onDeviceReady(JSONArray data, CallbackContext callbackContext) {
|
|
190
|
+
PWLog.noise(TAG, "onDeviceReady()");
|
|
191
|
+
|
|
155
192
|
JSONObject params = null;
|
|
156
193
|
try {
|
|
157
194
|
params = data.getJSONObject(0);
|
|
@@ -160,34 +197,37 @@ public class PushNotifications extends CordovaPlugin {
|
|
|
160
197
|
return false;
|
|
161
198
|
}
|
|
162
199
|
|
|
200
|
+
String appid = null;
|
|
163
201
|
try {
|
|
164
|
-
|
|
165
|
-
String appid = null;
|
|
166
202
|
if (params.has("appid")) {
|
|
167
203
|
appid = params.getString("appid");
|
|
168
204
|
} else {
|
|
169
205
|
appid = params.getString("pw_appid");
|
|
170
206
|
}
|
|
207
|
+
} catch (JSONException e) {
|
|
208
|
+
PWLog.error(TAG, "Missing appid parameter. Did you follow the guide correctly?", e);
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
171
211
|
|
|
172
|
-
|
|
173
|
-
Pushwoosh.getInstance().setSenderId(params.getString("projectid"));
|
|
212
|
+
String projectid = params.optString("projectid", "");
|
|
174
213
|
|
|
214
|
+
Pushwoosh.getInstance().setAppId(appid);
|
|
215
|
+
Pushwoosh.getInstance().setSenderId(projectid);
|
|
175
216
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
217
|
+
try {
|
|
218
|
+
processPendingPushNotifications();
|
|
219
|
+
} catch (Exception e) {
|
|
220
|
+
PWLog.error(TAG, "Failed to process pending push notifications", e);
|
|
221
|
+
}
|
|
180
222
|
|
|
181
|
-
|
|
182
|
-
doOnPushOpened(sStartPushData);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
223
|
+
sAppReady.set(true);
|
|
185
224
|
|
|
186
|
-
|
|
225
|
+
try {
|
|
226
|
+
processPersistedVoIPEvents();
|
|
187
227
|
} catch (Exception e) {
|
|
188
|
-
PWLog.error(TAG, "
|
|
189
|
-
return false;
|
|
228
|
+
PWLog.error(TAG, "Failed to process persisted VoIP events", e);
|
|
190
229
|
}
|
|
230
|
+
|
|
191
231
|
return true;
|
|
192
232
|
}
|
|
193
233
|
|
|
@@ -856,18 +896,6 @@ public class PushNotifications extends CordovaPlugin {
|
|
|
856
896
|
return true;
|
|
857
897
|
}
|
|
858
898
|
|
|
859
|
-
@Override
|
|
860
|
-
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
|
|
861
|
-
cordovaInterface = cordova;
|
|
862
|
-
callsAdapter = CallsAdapterFactory.create(cordova.getActivity().getApplicationContext());
|
|
863
|
-
callbackContextMap.put("answer", new ArrayList<CallbackContext>());
|
|
864
|
-
callbackContextMap.put("reject", new ArrayList<CallbackContext>());
|
|
865
|
-
callbackContextMap.put("hangup", new ArrayList<CallbackContext>());
|
|
866
|
-
callbackContextMap.put("voipPushPayload", new ArrayList<CallbackContext>());
|
|
867
|
-
callbackContextMap.put("voipDidCancelCall", new ArrayList<CallbackContext>());
|
|
868
|
-
callbackContextMap.put("voipDidFailToCancelCall", new ArrayList<CallbackContext>());
|
|
869
|
-
}
|
|
870
|
-
|
|
871
899
|
@Override
|
|
872
900
|
public boolean execute(String action, JSONArray data, CallbackContext callbackId) {
|
|
873
901
|
PWLog.debug(TAG, "Plugin Method Called: " + action);
|
|
@@ -1128,17 +1156,75 @@ public class PushNotifications extends CordovaPlugin {
|
|
|
1128
1156
|
return callsAdapter.speakerOff();
|
|
1129
1157
|
}
|
|
1130
1158
|
|
|
1159
|
+
private void processPendingPushNotifications() {
|
|
1160
|
+
PWLog.noise(TAG, "processPendingPushNotifications()");
|
|
1161
|
+
synchronized (sStartPushLock) {
|
|
1162
|
+
if (sReceivedPushData != null) {
|
|
1163
|
+
doOnPushReceived(sReceivedPushData);
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
if (sStartPushData != null) {
|
|
1167
|
+
doOnPushOpened(sStartPushData);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
private void processPersistedVoIPEvents() {
|
|
1173
|
+
PWLog.noise(TAG, "processPersistedVoIPEvents()");
|
|
1174
|
+
Context context = AndroidPlatformModule.getApplicationContext();
|
|
1175
|
+
if (context == null) {
|
|
1176
|
+
return;
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
List<VoIPEventStorage.StoredEvent> storedEvents = VoIPEventStorage.loadEvents(context);
|
|
1180
|
+
if (storedEvents.isEmpty()) {
|
|
1181
|
+
return;
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
PWLog.info(TAG, "Processing " + storedEvents.size() + " persisted VoIP events");
|
|
1185
|
+
|
|
1186
|
+
for (VoIPEventStorage.StoredEvent event : storedEvents) {
|
|
1187
|
+
emitVoipEvent(event.type, event.payload);
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
VoIPEventStorage.clearEvents(context);
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
private static void bufferVoipEvent(@NonNull String type, @NonNull JSONObject payload) {
|
|
1194
|
+
Context context = AndroidPlatformModule.getApplicationContext();
|
|
1195
|
+
if (context != null) {
|
|
1196
|
+
VoIPEventStorage.saveEvent(context, type, payload);
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1131
1200
|
public static void emitVoipEvent(@NonNull String type, @NonNull JSONObject payload) {
|
|
1201
|
+
PWLog.noise(TAG, "emitVoipEvent(), event type: " + type);
|
|
1202
|
+
|
|
1203
|
+
if (!isCordovaReady()) {
|
|
1204
|
+
PWLog.info(TAG, "Buffering VoIP event '" + type + "': Cordova not ready");
|
|
1205
|
+
bufferVoipEvent(type, payload);
|
|
1206
|
+
return;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1132
1209
|
ArrayList<CallbackContext> callbackContexts = getCallbackContexts().get(type);
|
|
1133
|
-
if (callbackContexts
|
|
1210
|
+
if (callbackContexts != null && !callbackContexts.isEmpty()) {
|
|
1211
|
+
for (final CallbackContext callbackContext : callbackContexts) {
|
|
1212
|
+
getCordovaInterface().getThreadPool().execute(() -> {
|
|
1213
|
+
PluginResult result = new PluginResult(PluginResult.Status.OK, payload);
|
|
1214
|
+
result.setKeepCallback(true);
|
|
1215
|
+
callbackContext.sendPluginResult(result);
|
|
1216
|
+
});
|
|
1217
|
+
}
|
|
1218
|
+
return;
|
|
1219
|
+
}
|
|
1134
1220
|
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
callbackContext.sendPluginResult(result);
|
|
1140
|
-
});
|
|
1221
|
+
if (!sAppReady.get()) {
|
|
1222
|
+
PWLog.info(TAG, "Buffering VoIP event '" + type + "': JS not ready");
|
|
1223
|
+
bufferVoipEvent(type, payload);
|
|
1224
|
+
return;
|
|
1141
1225
|
}
|
|
1226
|
+
|
|
1227
|
+
PWLog.warn(TAG, "No callback contexts registered for event: " + type);
|
|
1142
1228
|
}
|
|
1143
1229
|
|
|
1144
1230
|
private static JSONObject inboxMessageToJson(InboxMessage message) {
|
|
@@ -1165,4 +1251,4 @@ public class PushNotifications extends CordovaPlugin {
|
|
|
1165
1251
|
}
|
|
1166
1252
|
return object;
|
|
1167
1253
|
}
|
|
1168
|
-
}
|
|
1254
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
package com.pushwoosh.plugin.pushnotifications;
|
|
2
|
+
|
|
3
|
+
import android.content.Context;
|
|
4
|
+
import android.content.SharedPreferences;
|
|
5
|
+
import androidx.annotation.NonNull;
|
|
6
|
+
import com.pushwoosh.internal.utils.PWLog;
|
|
7
|
+
import org.json.JSONArray;
|
|
8
|
+
import org.json.JSONObject;
|
|
9
|
+
import java.util.ArrayList;
|
|
10
|
+
import java.util.List;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* VoIP Event Buffering Storage
|
|
14
|
+
*
|
|
15
|
+
* Provides persistent storage for VoIP events when WebView/JavaScript is not ready.
|
|
16
|
+
*/
|
|
17
|
+
public class VoIPEventStorage {
|
|
18
|
+
private static final String TAG = "VoIPEventStorage";
|
|
19
|
+
private static final String PREFS_NAME = "pushwoosh_voip_events";
|
|
20
|
+
private static final String KEY_BUFFERED_EVENTS = "buffered_events";
|
|
21
|
+
private static final long TTL_MILLIS = 24 * 60 * 60 * 1000; // 24 hours
|
|
22
|
+
private static final Object STORAGE_LOCK = new Object();
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Represents a stored VoIP event with metadata
|
|
26
|
+
*/
|
|
27
|
+
public static class StoredEvent {
|
|
28
|
+
public String type;
|
|
29
|
+
public JSONObject payload;
|
|
30
|
+
public long timestamp;
|
|
31
|
+
|
|
32
|
+
public StoredEvent(String type, JSONObject payload, long timestamp) {
|
|
33
|
+
this.type = type;
|
|
34
|
+
this.payload = payload;
|
|
35
|
+
this.timestamp = timestamp;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public boolean isExpired() {
|
|
39
|
+
return (System.currentTimeMillis() - timestamp) > TTL_MILLIS;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Save VoIP event to persistent storage
|
|
45
|
+
*/
|
|
46
|
+
public static boolean saveEvent(@NonNull Context context, @NonNull String type, @NonNull JSONObject payload) {
|
|
47
|
+
PWLog.noise(TAG, "saveEvent()");
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
synchronized (STORAGE_LOCK) {
|
|
51
|
+
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
|
|
52
|
+
String existingData = prefs.getString(KEY_BUFFERED_EVENTS, "[]");
|
|
53
|
+
JSONArray events = new JSONArray(existingData);
|
|
54
|
+
|
|
55
|
+
JSONObject event = new JSONObject();
|
|
56
|
+
event.put("type", type);
|
|
57
|
+
event.put("payload", payload);
|
|
58
|
+
event.put("timestamp", System.currentTimeMillis());
|
|
59
|
+
|
|
60
|
+
events.put(event);
|
|
61
|
+
|
|
62
|
+
boolean success = prefs.edit()
|
|
63
|
+
.putString(KEY_BUFFERED_EVENTS, events.toString())
|
|
64
|
+
.commit();
|
|
65
|
+
|
|
66
|
+
return success;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
} catch (Exception e) {
|
|
70
|
+
PWLog.error(TAG, "Failed to save VoIP event", e);
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
private static StoredEvent parseStoredEvent(@NonNull JSONObject eventObj) throws Exception {
|
|
76
|
+
String type = eventObj.getString("type");
|
|
77
|
+
JSONObject payload = eventObj.getJSONObject("payload");
|
|
78
|
+
long timestamp = eventObj.getLong("timestamp");
|
|
79
|
+
return new StoredEvent(type, payload, timestamp);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Load all non-expired events from storage.
|
|
84
|
+
*/
|
|
85
|
+
public static List<StoredEvent> loadEvents(@NonNull Context context) {
|
|
86
|
+
PWLog.noise(TAG, "loadEvents()");
|
|
87
|
+
|
|
88
|
+
List<StoredEvent> result = new ArrayList<>();
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
synchronized (STORAGE_LOCK) {
|
|
92
|
+
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
|
|
93
|
+
String data = prefs.getString(KEY_BUFFERED_EVENTS, "[]");
|
|
94
|
+
JSONArray events = new JSONArray(data);
|
|
95
|
+
|
|
96
|
+
for (int i = 0; i < events.length(); i++) {
|
|
97
|
+
try {
|
|
98
|
+
StoredEvent event = parseStoredEvent(events.getJSONObject(i));
|
|
99
|
+
|
|
100
|
+
if (event.isExpired()) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
result.add(event);
|
|
105
|
+
} catch (Exception e) {
|
|
106
|
+
PWLog.error(TAG, "Failed to parse VoIP event at index " + i + ", skipping", e);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
} catch (Exception e) {
|
|
112
|
+
PWLog.error(TAG, "Failed to load VoIP events", e);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
public static void clearEvents(@NonNull Context context) {
|
|
119
|
+
PWLog.noise(TAG, "clearEvents()");
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
synchronized (STORAGE_LOCK) {
|
|
123
|
+
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
|
|
124
|
+
prefs.edit().remove(KEY_BUFFERED_EVENTS).commit();
|
|
125
|
+
}
|
|
126
|
+
} catch (Exception e) {
|
|
127
|
+
PWLog.error(TAG, "Failed to clear VoIP events", e);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
package/src/android/src/com/pushwoosh/plugin/pushnotifications/calls/PWCordovaCallEventListener.java
CHANGED
|
@@ -13,82 +13,109 @@ import com.pushwoosh.internal.platform.AndroidPlatformModule;
|
|
|
13
13
|
import com.pushwoosh.internal.utils.PWLog;
|
|
14
14
|
|
|
15
15
|
public class PWCordovaCallEventListener implements CallEventListener {
|
|
16
|
+
|
|
17
|
+
private static final String TAG = "PWCordovaCallEventListener";
|
|
16
18
|
private static final Object sCurrentCallLock = new Object();
|
|
17
19
|
private static Bundle currentCallInfo = null;
|
|
18
20
|
|
|
21
|
+
private void setCurrentCallInfo(Bundle bundle) {
|
|
22
|
+
synchronized (sCurrentCallLock) {
|
|
23
|
+
currentCallInfo = bundle;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
19
26
|
|
|
20
|
-
|
|
21
|
-
public void onAnswer(@NonNull PushwooshVoIPMessage pushwooshVoIPMessage, int i) {
|
|
27
|
+
private void clearCurrentCallInfo() {
|
|
22
28
|
synchronized (sCurrentCallLock) {
|
|
23
|
-
currentCallInfo =
|
|
29
|
+
currentCallInfo = null;
|
|
24
30
|
}
|
|
25
|
-
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public static Bundle getCurrentCallInfo() {
|
|
34
|
+
synchronized (sCurrentCallLock) {
|
|
35
|
+
return currentCallInfo;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private void launchMainActivity() {
|
|
40
|
+
PWLog.noise(TAG, "launchMainActivity()");
|
|
26
41
|
try {
|
|
27
42
|
Context context = AndroidPlatformModule.getApplicationContext();
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
43
|
+
if (context == null) {
|
|
44
|
+
PWLog.error(TAG, "cant launch activity: context is null");
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
|
|
48
|
+
if (launchIntent == null) {
|
|
49
|
+
PWLog.error(TAG, "cant launch activity: launchIntent is null");
|
|
50
|
+
return;
|
|
34
51
|
}
|
|
52
|
+
|
|
53
|
+
launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
|
54
|
+
context.startActivity(launchIntent);
|
|
35
55
|
} catch (Exception e) {
|
|
36
|
-
PWLog.error(
|
|
56
|
+
PWLog.error(TAG, "Failed to launch activity", e);
|
|
37
57
|
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@Override
|
|
62
|
+
public void onCreateIncomingConnection(@Nullable Bundle bundle) {
|
|
63
|
+
PWLog.noise(TAG, "onCreateIncomingConnection()");
|
|
64
|
+
|
|
65
|
+
setCurrentCallInfo(bundle);
|
|
66
|
+
PushwooshCallsAdapter.onCreateIncomingConnection(bundle);
|
|
67
|
+
}
|
|
38
68
|
|
|
69
|
+
|
|
70
|
+
@Override
|
|
71
|
+
public void onAnswer(@NonNull PushwooshVoIPMessage pushwooshVoIPMessage, int i) {
|
|
72
|
+
PWLog.noise(TAG, "onAnswer()");
|
|
73
|
+
|
|
74
|
+
setCurrentCallInfo(pushwooshVoIPMessage.getRawPayload());
|
|
39
75
|
PushwooshCallsAdapter.onAnswer(pushwooshVoIPMessage);
|
|
76
|
+
launchMainActivity();
|
|
40
77
|
}
|
|
41
78
|
|
|
42
79
|
@Override
|
|
43
80
|
public void onReject(@NonNull PushwooshVoIPMessage pushwooshVoIPMessage) {
|
|
81
|
+
PWLog.noise(TAG, "onReject()");
|
|
82
|
+
|
|
44
83
|
PushwooshCallsAdapter.onReject(pushwooshVoIPMessage);
|
|
45
|
-
|
|
46
|
-
currentCallInfo = null;
|
|
47
|
-
}
|
|
84
|
+
clearCurrentCallInfo();
|
|
48
85
|
}
|
|
49
86
|
|
|
50
87
|
@Override
|
|
51
88
|
public void onDisconnect(@NonNull PushwooshVoIPMessage pushwooshVoIPMessage) {
|
|
52
|
-
|
|
53
|
-
synchronized (sCurrentCallLock) {
|
|
54
|
-
currentCallInfo = null;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
89
|
+
PWLog.noise(TAG, "onDisconnect()");
|
|
57
90
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
synchronized (sCurrentCallLock) {
|
|
61
|
-
currentCallInfo = bundle;
|
|
62
|
-
}
|
|
63
|
-
PushwooshCallsAdapter.onCreateIncomingConnection(bundle);
|
|
91
|
+
PushwooshCallsAdapter.onDisconnect(pushwooshVoIPMessage);
|
|
92
|
+
clearCurrentCallInfo();
|
|
64
93
|
}
|
|
65
94
|
|
|
66
95
|
@Override
|
|
67
96
|
public void onCallAdded(@NonNull PushwooshVoIPMessage pushwooshVoIPMessage) {
|
|
97
|
+
PWLog.noise(TAG, "onCallAdded()");
|
|
68
98
|
//stub
|
|
69
99
|
}
|
|
70
100
|
|
|
71
101
|
@Override
|
|
72
102
|
public void onCallRemoved(@NonNull PushwooshVoIPMessage pushwooshVoIPMessage) {
|
|
103
|
+
PWLog.noise(TAG, "onCallRemoved()");
|
|
73
104
|
//stub
|
|
74
105
|
}
|
|
75
106
|
|
|
76
107
|
@Override
|
|
77
108
|
public void onCallCancelled(@NonNull PushwooshVoIPMessage pushwooshVoIPMessage) {
|
|
109
|
+
PWLog.noise(TAG, "onCallCancelled()");
|
|
110
|
+
|
|
78
111
|
PushwooshCallsAdapter.onCallCancelled(pushwooshVoIPMessage);
|
|
79
|
-
|
|
80
|
-
currentCallInfo = null;
|
|
81
|
-
}
|
|
112
|
+
clearCurrentCallInfo();
|
|
82
113
|
}
|
|
83
114
|
|
|
84
115
|
@Override
|
|
85
116
|
public void onCallCancellationFailed(@Nullable String callId, @Nullable String reason) {
|
|
86
|
-
|
|
87
|
-
}
|
|
117
|
+
PWLog.noise(TAG, "onCallCancellationFailed()");
|
|
88
118
|
|
|
89
|
-
|
|
90
|
-
synchronized (sCurrentCallLock) {
|
|
91
|
-
return currentCallInfo;
|
|
92
|
-
}
|
|
119
|
+
PushwooshCallsAdapter.onCallCancellationFailed(callId, reason);
|
|
93
120
|
}
|
|
94
121
|
}
|
package/src/android/src/com/pushwoosh/plugin/pushnotifications/calls/PushwooshCallsAdapter.java
CHANGED
|
@@ -30,6 +30,7 @@ public class PushwooshCallsAdapter implements CallsAdapter {
|
|
|
30
30
|
|
|
31
31
|
@Override
|
|
32
32
|
public boolean setVoipAppCode(JSONArray data, CallbackContext callbackContext) {
|
|
33
|
+
PWLog.noise(TAG, "setVoipAppCode()");
|
|
33
34
|
try {
|
|
34
35
|
String appCode = data.getString(0);
|
|
35
36
|
Pushwoosh.getInstance().addAlternativeAppCode(appCode);
|
|
@@ -42,6 +43,7 @@ public class PushwooshCallsAdapter implements CallsAdapter {
|
|
|
42
43
|
|
|
43
44
|
@Override
|
|
44
45
|
public boolean requestCallPermission(JSONArray data, final CallbackContext callbackContext) {
|
|
46
|
+
PWLog.noise(TAG, "requestCallPermission()");
|
|
45
47
|
try {
|
|
46
48
|
PushwooshCallSettings.requestCallPermissions(new CallPermissionsCallback() {
|
|
47
49
|
@Override
|
|
@@ -59,6 +61,7 @@ public class PushwooshCallsAdapter implements CallsAdapter {
|
|
|
59
61
|
|
|
60
62
|
@Override
|
|
61
63
|
public boolean getCallPermissionStatus(JSONArray data, CallbackContext callbackContext) {
|
|
64
|
+
PWLog.noise(TAG, "getCallPermissionStatus()");
|
|
62
65
|
try {
|
|
63
66
|
int status = PushwooshCallSettings.getCallPermissionStatus();
|
|
64
67
|
callbackContext.success(status);
|
|
@@ -71,6 +74,7 @@ public class PushwooshCallsAdapter implements CallsAdapter {
|
|
|
71
74
|
|
|
72
75
|
@Override
|
|
73
76
|
public boolean registerEvent(JSONArray data, CallbackContext callbackContext) {
|
|
77
|
+
PWLog.noise(TAG, "registerEvent()");
|
|
74
78
|
try {
|
|
75
79
|
|
|
76
80
|
String eventType = data.getString(0);
|
|
@@ -86,6 +90,7 @@ public class PushwooshCallsAdapter implements CallsAdapter {
|
|
|
86
90
|
|
|
87
91
|
@Override
|
|
88
92
|
public boolean unregisterEvent(JSONArray data, CallbackContext callbackContext) {
|
|
93
|
+
PWLog.noise(TAG, "unregisterEvent()");
|
|
89
94
|
try {
|
|
90
95
|
String eventType = data.getString(0);
|
|
91
96
|
ArrayList<CallbackContext> callbackContextList = getCallbackContextMap().get(eventType);
|
|
@@ -104,6 +109,7 @@ public class PushwooshCallsAdapter implements CallsAdapter {
|
|
|
104
109
|
|
|
105
110
|
@Override
|
|
106
111
|
public boolean endCall(JSONArray data, CallbackContext callbackContext) {
|
|
112
|
+
PWLog.noise(TAG, "endCall()");
|
|
107
113
|
Context context = AndroidPlatformModule.getApplicationContext();
|
|
108
114
|
Intent endCallIntent = new Intent(context, PushwooshCallReceiver.class);
|
|
109
115
|
endCallIntent.putExtras(PWCordovaCallEventListener.getCurrentCallInfo());
|
|
@@ -115,6 +121,7 @@ public class PushwooshCallsAdapter implements CallsAdapter {
|
|
|
115
121
|
|
|
116
122
|
@Override
|
|
117
123
|
public boolean initializeVoIPParameters(JSONArray data, CallbackContext callbackContext) {
|
|
124
|
+
PWLog.noise(TAG, "initializeVoIPParameters()");
|
|
118
125
|
try {
|
|
119
126
|
String callSound = data.getString(1);
|
|
120
127
|
if (callSound!= null && !callSound.isEmpty()){
|
|
@@ -129,6 +136,7 @@ public class PushwooshCallsAdapter implements CallsAdapter {
|
|
|
129
136
|
|
|
130
137
|
@Override
|
|
131
138
|
public boolean setIncomingCallTimeout(JSONArray data, CallbackContext callbackContext) {
|
|
139
|
+
PWLog.noise(TAG, "setIncomingCallTimeout()");
|
|
132
140
|
try {
|
|
133
141
|
double timeout = data.getDouble(0);
|
|
134
142
|
PushwooshCallSettings.setIncomingCallTimeout(timeout);
|
|
@@ -141,6 +149,7 @@ public class PushwooshCallsAdapter implements CallsAdapter {
|
|
|
141
149
|
|
|
142
150
|
@Override
|
|
143
151
|
public boolean mute() {
|
|
152
|
+
PWLog.noise(TAG, "mute()");
|
|
144
153
|
try {
|
|
145
154
|
AudioManager audioManager = (AudioManager) getCordovaInterface().getActivity().getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
|
|
146
155
|
audioManager.setMicrophoneMute(true);
|
|
@@ -153,6 +162,7 @@ public class PushwooshCallsAdapter implements CallsAdapter {
|
|
|
153
162
|
|
|
154
163
|
@Override
|
|
155
164
|
public boolean unmute() {
|
|
165
|
+
PWLog.noise(TAG, "unmute()");
|
|
156
166
|
try {
|
|
157
167
|
AudioManager audioManager = (AudioManager) getCordovaInterface().getActivity().getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
|
|
158
168
|
audioManager.setMicrophoneMute(false);
|
|
@@ -165,6 +175,7 @@ public class PushwooshCallsAdapter implements CallsAdapter {
|
|
|
165
175
|
|
|
166
176
|
@Override
|
|
167
177
|
public boolean speakerOn() {
|
|
178
|
+
PWLog.noise(TAG, "speakerOn()");
|
|
168
179
|
try {
|
|
169
180
|
AudioManager audioManager = (AudioManager) getCordovaInterface().getActivity().getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
|
|
170
181
|
audioManager.setSpeakerphoneOn(true);
|
|
@@ -177,6 +188,7 @@ public class PushwooshCallsAdapter implements CallsAdapter {
|
|
|
177
188
|
|
|
178
189
|
@Override
|
|
179
190
|
public boolean speakerOff() {
|
|
191
|
+
PWLog.noise(TAG, "speakerOff()");
|
|
180
192
|
try {
|
|
181
193
|
AudioManager audioManager = (AudioManager) getCordovaInterface().getActivity().getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
|
|
182
194
|
audioManager.setSpeakerphoneOn(false);
|
|
@@ -188,27 +200,33 @@ public class PushwooshCallsAdapter implements CallsAdapter {
|
|
|
188
200
|
}
|
|
189
201
|
|
|
190
202
|
public static void onAnswer(PushwooshVoIPMessage voIPMessage) {
|
|
203
|
+
PWLog.noise(TAG, "onAnswer()");
|
|
191
204
|
PushNotifications.emitVoipEvent("answer", parseVoIPMessage(voIPMessage));
|
|
192
205
|
}
|
|
193
206
|
|
|
194
207
|
public static void onReject(PushwooshVoIPMessage voIPMessage) {
|
|
208
|
+
PWLog.noise(TAG, "onReject()");
|
|
195
209
|
PushNotifications.emitVoipEvent("reject", parseVoIPMessage(voIPMessage));
|
|
196
210
|
}
|
|
197
211
|
|
|
198
212
|
public static void onDisconnect(PushwooshVoIPMessage voIPMessage) {
|
|
213
|
+
PWLog.noise(TAG, "onDisconnect()");
|
|
199
214
|
PushNotifications.emitVoipEvent("hangup", parseVoIPMessage(voIPMessage));
|
|
200
215
|
}
|
|
201
216
|
|
|
202
217
|
public static void onCreateIncomingConnection(Bundle bundle) {
|
|
218
|
+
PWLog.noise(TAG, "onCreateIncomingConnection()");
|
|
203
219
|
PushwooshVoIPMessage voipMessage = new PushwooshVoIPMessage(bundle);
|
|
204
220
|
PushNotifications.emitVoipEvent("voipPushPayload", parseVoIPMessage(voipMessage));
|
|
205
221
|
}
|
|
206
222
|
|
|
207
223
|
public static void onCallCancelled(PushwooshVoIPMessage voIPMessage) {
|
|
224
|
+
PWLog.noise(TAG, "onCallCancelled()");
|
|
208
225
|
PushNotifications.emitVoipEvent("voipDidCancelCall", parseVoIPMessage(voIPMessage));
|
|
209
226
|
}
|
|
210
227
|
|
|
211
228
|
public static void onCallCancellationFailed(String callId, String reason) {
|
|
229
|
+
PWLog.noise(TAG, "onCallCancellationFailed()");
|
|
212
230
|
org.json.JSONObject payload = new org.json.JSONObject();
|
|
213
231
|
try {
|
|
214
232
|
payload.put("callId", callId != null ? callId : "");
|
|
@@ -218,6 +236,7 @@ public class PushwooshCallsAdapter implements CallsAdapter {
|
|
|
218
236
|
}
|
|
219
237
|
|
|
220
238
|
private static org.json.JSONObject parseVoIPMessage(PushwooshVoIPMessage message) {
|
|
239
|
+
PWLog.noise(TAG, "parseVoIPMessage()");
|
|
221
240
|
org.json.JSONObject payload = new org.json.JSONObject();
|
|
222
241
|
try {
|
|
223
242
|
Bundle rawBundle = message.getRawPayload();
|