cordova-plugin-salus-call 0.2.0 → 0.2.2
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
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cordova-plugin-salus-call",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Integração nativa de chamadas VoIP para o aplicativo Salus.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"private": false,
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"engines": {
|
|
31
31
|
"cordovaDependencies": {
|
|
32
|
-
"0.2.
|
|
32
|
+
"0.2.2": {
|
|
33
33
|
"cordova": ">=12.0.0",
|
|
34
34
|
"cordova-android": ">=14.0.0"
|
|
35
35
|
}
|
package/plugin.xml
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
|
3
3
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
4
4
|
id="cordova-plugin-salus-call"
|
|
5
|
-
version="0.2.
|
|
5
|
+
version="0.2.2">
|
|
6
6
|
<name>Salus Call</name>
|
|
7
7
|
<description>Ponte nativa para chamadas de interfone do Salus.</description>
|
|
8
8
|
<license>UNLICENSED</license>
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
<config-file target="AndroidManifest.xml" parent="/manifest">
|
|
16
16
|
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
|
|
17
17
|
<uses-permission android:name="android.permission.VIBRATE" />
|
|
18
|
+
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
|
19
|
+
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
|
18
20
|
</config-file>
|
|
19
21
|
<config-file target="AndroidManifest.xml" parent="/manifest/application">
|
|
20
22
|
<provider
|
|
@@ -24,13 +24,8 @@ public class SalusCallActionReceiver extends BroadcastReceiver {
|
|
|
24
24
|
SalusCallPlugin.dispatchEvent(context, event);
|
|
25
25
|
|
|
26
26
|
if (answered) {
|
|
27
|
-
Intent launch =
|
|
28
|
-
|
|
29
|
-
launch.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
|
30
|
-
launch.putExtra(SalusCallNotificationManager.EXTRA_CALL, call.toString());
|
|
31
|
-
launch.putExtra("salus_call_action", "answer");
|
|
32
|
-
context.startActivity(launch);
|
|
33
|
-
}
|
|
27
|
+
Intent launch = SalusCallNotificationManager.launchIntent(context, call, "answer");
|
|
28
|
+
context.startActivity(launch);
|
|
34
29
|
}
|
|
35
30
|
} catch (Exception ignored) {}
|
|
36
31
|
}
|
|
@@ -32,7 +32,7 @@ public final class SalusCallNotificationManager {
|
|
|
32
32
|
int notificationId = notificationId(callId);
|
|
33
33
|
|
|
34
34
|
Person caller = new Person.Builder().setName(callerName).setImportant(true).build();
|
|
35
|
-
PendingIntent answer =
|
|
35
|
+
PendingIntent answer = answerIntent(context, call, notificationId + 1);
|
|
36
36
|
PendingIntent reject = actionIntent(context, ACTION_REJECT, call, notificationId + 2);
|
|
37
37
|
PendingIntent open = openAppIntent(context, call, notificationId + 3);
|
|
38
38
|
|
|
@@ -100,13 +100,24 @@ public final class SalusCallNotificationManager {
|
|
|
100
100
|
return PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
private static PendingIntent answerIntent(Context context, JSONObject call, int requestCode) {
|
|
104
|
+
Intent intent = launchIntent(context, call, "answer");
|
|
105
|
+
intent.setAction(ACTION_ANSWER);
|
|
106
|
+
return PendingIntent.getActivity(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
|
|
107
|
+
}
|
|
108
|
+
|
|
103
109
|
private static PendingIntent openAppIntent(Context context, JSONObject call, int requestCode) {
|
|
110
|
+
Intent intent = launchIntent(context, call, "open");
|
|
111
|
+
return PendingIntent.getActivity(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
static Intent launchIntent(Context context, JSONObject call, String action) {
|
|
104
115
|
Intent intent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
|
|
105
116
|
if (intent == null) intent = new Intent();
|
|
106
117
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
|
107
118
|
intent.putExtra(EXTRA_CALL, call.toString());
|
|
108
|
-
intent.putExtra("salus_call_action",
|
|
109
|
-
return
|
|
119
|
+
intent.putExtra("salus_call_action", action);
|
|
120
|
+
return intent;
|
|
110
121
|
}
|
|
111
122
|
|
|
112
123
|
private static int notificationId(String callId) {
|
|
@@ -2,6 +2,10 @@ package br.com.salus.call;
|
|
|
2
2
|
|
|
3
3
|
import android.content.Context;
|
|
4
4
|
import android.content.Intent;
|
|
5
|
+
import android.media.AudioAttributes;
|
|
6
|
+
import android.media.AudioFocusRequest;
|
|
7
|
+
import android.media.AudioManager;
|
|
8
|
+
import android.os.Build;
|
|
5
9
|
|
|
6
10
|
import org.apache.cordova.CallbackContext;
|
|
7
11
|
import org.apache.cordova.CordovaInterface;
|
|
@@ -15,11 +19,14 @@ import org.json.JSONObject;
|
|
|
15
19
|
public class SalusCallPlugin extends CordovaPlugin {
|
|
16
20
|
private static SalusCallPlugin activeInstance;
|
|
17
21
|
private CallbackContext eventCallback;
|
|
22
|
+
private AudioManager audioManager;
|
|
23
|
+
private AudioFocusRequest audioFocusRequest;
|
|
18
24
|
|
|
19
25
|
@Override
|
|
20
26
|
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
|
|
21
27
|
super.initialize(cordova, webView);
|
|
22
28
|
activeInstance = this;
|
|
29
|
+
handleLaunchIntent(cordova.getActivity().getIntent());
|
|
23
30
|
}
|
|
24
31
|
|
|
25
32
|
@Override
|
|
@@ -46,17 +53,28 @@ public class SalusCallPlugin extends CordovaPlugin {
|
|
|
46
53
|
callback.success(call);
|
|
47
54
|
return true;
|
|
48
55
|
case "answer":
|
|
56
|
+
prepareAudioSession();
|
|
49
57
|
handleLocalAction("answered", args.optString(0, ""), "answered_in_app");
|
|
50
58
|
callback.success();
|
|
51
59
|
return true;
|
|
52
60
|
case "reject":
|
|
61
|
+
releaseAudioSession();
|
|
53
62
|
handleLocalAction("rejected", args.optString(0, ""), args.optString(1, "declined"));
|
|
54
63
|
callback.success();
|
|
55
64
|
return true;
|
|
56
65
|
case "hangup":
|
|
66
|
+
releaseAudioSession();
|
|
57
67
|
handleLocalAction("ended", args.optString(0, ""), args.optString(1, "local_hangup"));
|
|
58
68
|
callback.success();
|
|
59
69
|
return true;
|
|
70
|
+
case "prepareAudio":
|
|
71
|
+
prepareAudioSession();
|
|
72
|
+
callback.success();
|
|
73
|
+
return true;
|
|
74
|
+
case "releaseAudio":
|
|
75
|
+
releaseAudioSession();
|
|
76
|
+
callback.success();
|
|
77
|
+
return true;
|
|
60
78
|
case "startCall":
|
|
61
79
|
case "setMuted":
|
|
62
80
|
case "setVideoEnabled":
|
|
@@ -75,6 +93,7 @@ public class SalusCallPlugin extends CordovaPlugin {
|
|
|
75
93
|
result.put("audio", false);
|
|
76
94
|
result.put("video", false);
|
|
77
95
|
result.put("incomingCallUi", true);
|
|
96
|
+
result.put("audioSession", true);
|
|
78
97
|
return result;
|
|
79
98
|
}
|
|
80
99
|
|
|
@@ -103,11 +122,13 @@ public class SalusCallPlugin extends CordovaPlugin {
|
|
|
103
122
|
|
|
104
123
|
@Override
|
|
105
124
|
public void onNewIntent(Intent intent) {
|
|
125
|
+
handleLaunchIntent(intent);
|
|
106
126
|
emitPendingEvents();
|
|
107
127
|
}
|
|
108
128
|
|
|
109
129
|
@Override
|
|
110
130
|
public void onDestroy() {
|
|
131
|
+
releaseAudioSession();
|
|
111
132
|
if (activeInstance == this) activeInstance = null;
|
|
112
133
|
super.onDestroy();
|
|
113
134
|
}
|
|
@@ -127,4 +148,69 @@ public class SalusCallPlugin extends CordovaPlugin {
|
|
|
127
148
|
event.put("timestamp", System.currentTimeMillis());
|
|
128
149
|
emitEvent(event);
|
|
129
150
|
}
|
|
151
|
+
|
|
152
|
+
private void handleLaunchIntent(Intent intent) {
|
|
153
|
+
if (intent == null) return;
|
|
154
|
+
|
|
155
|
+
String action = intent.getStringExtra("salus_call_action");
|
|
156
|
+
String callJson = intent.getStringExtra(SalusCallNotificationManager.EXTRA_CALL);
|
|
157
|
+
if (action == null || callJson == null || callJson.isEmpty()) return;
|
|
158
|
+
|
|
159
|
+
intent.removeExtra("salus_call_action");
|
|
160
|
+
intent.removeExtra(SalusCallNotificationManager.EXTRA_CALL);
|
|
161
|
+
|
|
162
|
+
try {
|
|
163
|
+
JSONObject call = new JSONObject(callJson);
|
|
164
|
+
String callId = call.optString("callId", "");
|
|
165
|
+
SalusCallNotificationManager.cancel(cordova.getContext(), callId);
|
|
166
|
+
|
|
167
|
+
JSONObject event = new JSONObject();
|
|
168
|
+
if ("answer".equals(action)) {
|
|
169
|
+
prepareAudioSession();
|
|
170
|
+
event.put("type", "answered");
|
|
171
|
+
event.put("reason", "system_answer");
|
|
172
|
+
} else {
|
|
173
|
+
event.put("type", "opened");
|
|
174
|
+
event.put("reason", "notification_open");
|
|
175
|
+
}
|
|
176
|
+
event.put("callId", callId);
|
|
177
|
+
event.put("call", call);
|
|
178
|
+
event.put("timestamp", System.currentTimeMillis());
|
|
179
|
+
dispatchEvent(cordova.getContext(), event);
|
|
180
|
+
} catch (Exception ignored) {}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
private void prepareAudioSession() {
|
|
184
|
+
if (audioManager != null) return;
|
|
185
|
+
audioManager = (AudioManager) cordova.getContext().getSystemService(Context.AUDIO_SERVICE);
|
|
186
|
+
if (audioManager == null) return;
|
|
187
|
+
|
|
188
|
+
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
|
|
189
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
190
|
+
AudioAttributes attributes = new AudioAttributes.Builder()
|
|
191
|
+
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
|
|
192
|
+
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
|
|
193
|
+
.build();
|
|
194
|
+
audioFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT)
|
|
195
|
+
.setAudioAttributes(attributes)
|
|
196
|
+
.setAcceptsDelayedFocusGain(false)
|
|
197
|
+
.setOnAudioFocusChangeListener(focusChange -> {})
|
|
198
|
+
.build();
|
|
199
|
+
audioManager.requestAudioFocus(audioFocusRequest);
|
|
200
|
+
} else {
|
|
201
|
+
audioManager.requestAudioFocus(null, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
private void releaseAudioSession() {
|
|
206
|
+
if (audioManager == null) return;
|
|
207
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && audioFocusRequest != null) {
|
|
208
|
+
audioManager.abandonAudioFocusRequest(audioFocusRequest);
|
|
209
|
+
} else {
|
|
210
|
+
audioManager.abandonAudioFocus(null);
|
|
211
|
+
}
|
|
212
|
+
audioManager.setMode(AudioManager.MODE_NORMAL);
|
|
213
|
+
audioFocusRequest = null;
|
|
214
|
+
audioManager = null;
|
|
215
|
+
}
|
|
130
216
|
}
|
package/www/SalusCall.js
CHANGED
|
@@ -64,6 +64,14 @@ module.exports = {
|
|
|
64
64
|
return callNative('hangup', [callId, reason || 'local_hangup']);
|
|
65
65
|
},
|
|
66
66
|
|
|
67
|
+
prepareAudio: function() {
|
|
68
|
+
return callNative('prepareAudio');
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
releaseAudio: function() {
|
|
72
|
+
return callNative('releaseAudio');
|
|
73
|
+
},
|
|
74
|
+
|
|
67
75
|
setMuted: function(muted) {
|
|
68
76
|
return callNative('setMuted', [Boolean(muted)]);
|
|
69
77
|
},
|