blob: 622f58fa07a60437a908b30d909d2cd440b5054e [file] [log] [blame]
Adrien BĂ©raud04d822c2015-04-02 17:44:36 -04001package cx.ring.service;
2
3import android.content.Intent;
4import android.os.Bundle;
5import android.util.Log;
6import cx.ring.client.CallActivity;
7import cx.ring.model.account.Account;
8import cx.ring.utils.SwigNativeConverter;
9
10import java.util.ArrayList;
11import java.util.Map;
12
13import cx.ring.model.CallContact;
14import cx.ring.model.Conference;
15import cx.ring.model.SecureSipCall;
16import cx.ring.model.SipCall;
17import cx.ring.model.SipMessage;
18
19public class CallManagerCallBack extends Callback {
20
21 private static final String TAG = "CallManagerCallBack";
22 private SipService mService;
23
24 static public final String CALL_STATE_CHANGED = "call-state-changed";
25 static public final String INCOMING_CALL = "incoming-call";
26 static public final String INCOMING_TEXT = "incoming-text";
27 static public final String CONF_CREATED = "conf_created";
28 static public final String CONF_REMOVED = "conf_removed";
29 static public final String CONF_CHANGED = "conf_changed";
30 static public final String RECORD_STATE_CHANGED = "record_state";
31
32 static public final String ZRTP_ON = "secure_zrtp_on";
33 static public final String ZRTP_OFF = "secure_zrtp_off";
34 static public final String DISPLAY_SAS = "display_sas";
35 static public final String ZRTP_NEGOTIATION_FAILED = "zrtp_nego_failed";
36 static public final String ZRTP_NOT_SUPPORTED = "zrtp_not_supported";
37
38 static public final String RTCP_REPORT_RECEIVED = "on_rtcp_report_received";
39
40
41 public CallManagerCallBack(SipService context) {
42 super();
43 mService = context;
44 }
45
46 @Override
47 public void callOnStateChange(String callID, String newState) {
48 Log.d(TAG, "on_call_state_changed : (" + callID + ", " + newState + ")");
49
50 Conference toUpdate = mService.findConference(callID);
51
52 if (toUpdate == null) {
53 return;
54 }
55
56 Intent intent = new Intent(CALL_STATE_CHANGED);
57 intent.putExtra("CallID", callID);
58 intent.putExtra("State", newState);
59
60 if (newState.equals("RINGING")) {
61 toUpdate.setCallState(callID, SipCall.state.CALL_STATE_RINGING);
62 } else if (newState.equals("CURRENT")) {
63 if (toUpdate.isRinging()) {
64 toUpdate.getCallById(callID).setTimestampStart_(System.currentTimeMillis());
65 }
66 toUpdate.setCallState(callID, SipCall.state.CALL_STATE_CURRENT);
67 } else if (newState.equals("HUNGUP")) {
68 Log.d(TAG, "Hanging up " + callID);
69 SipCall call = toUpdate.getCallById(callID);
70 if (!toUpdate.hasMultipleParticipants()) {
71 if (toUpdate.isRinging() && toUpdate.isIncoming()) {
72 mService.mNotificationManager.publishMissedCallNotification(mService.getConferences().get(callID));
73 }
74 toUpdate.setCallState(callID, SipCall.state.CALL_STATE_HUNGUP);
75 mService.mHistoryManager.insertNewEntry(toUpdate);
76 mService.getConferences().remove(toUpdate.getId());
77 } else {
78 toUpdate.setCallState(callID, SipCall.state.CALL_STATE_HUNGUP);
79 mService.mHistoryManager.insertNewEntry(call);
80 }
81 } else if (newState.equals("BUSY")) {
82 toUpdate.setCallState(callID, SipCall.state.CALL_STATE_BUSY);
83 mService.getConferences().remove(toUpdate.getId());
84 } else if (newState.equals("FAILURE")) {
85 toUpdate.setCallState(callID, SipCall.state.CALL_STATE_FAILURE);
86 mService.getConferences().remove(toUpdate.getId());
87 Ringservice.sflph_call_hang_up(callID);
88 } else if (newState.equals("HOLD")) {
89 toUpdate.setCallState(callID, SipCall.state.CALL_STATE_HOLD);
90 } else if (newState.equals("UNHOLD")) {
91 toUpdate.setCallState(callID, SipCall.state.CALL_STATE_CURRENT);
92 }
93 intent.putExtra("conference", toUpdate);
94 mService.sendBroadcast(intent);
95 }
96
97
98 @Override
99 public void callOnIncomingCall(String accountID, String callID, String from) {
100 Log.d(TAG, "on_incoming_call(" + accountID + ", " + callID + ", " + from + ")");
101
102 try {
103 StringMap details = Ringservice.sflph_config_get_account_details(accountID);
104 VectMap credentials = Ringservice.sflph_config_get_credentials(accountID);
105 Account acc = new Account(accountID, SwigNativeConverter.convertAccountToNative(details), SwigNativeConverter.convertCredentialsToNative(credentials));
106
107 Bundle args = new Bundle();
108 args.putString(SipCall.ID, callID);
109 args.putParcelable(SipCall.ACCOUNT, acc);
110 args.putInt(SipCall.STATE, SipCall.state.CALL_STATE_RINGING);
111 args.putInt(SipCall.TYPE, SipCall.direction.CALL_TYPE_INCOMING);
112
113 CallContact unknow = CallContact.ContactBuilder.buildUnknownContact(from);
114 args.putParcelable(SipCall.CONTACT, unknow);
115
116 Intent toSend = new Intent(CallManagerCallBack.INCOMING_CALL);
117 toSend.setClass(mService, CallActivity.class);
118 toSend.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
119 SipCall newCall = new SipCall(args);
120 newCall.setTimestampStart_(System.currentTimeMillis());
121
122 Conference toAdd;
123 if (acc.useSecureLayer()) {
124 SecureSipCall secureCall = new SecureSipCall(newCall);
125 toAdd = new Conference(secureCall);
126 } else {
127 toAdd = new Conference(newCall);
128 }
129
130 mService.getConferences().put(toAdd.getId(), toAdd);
131
132 Bundle bundle = new Bundle();
133 bundle.putParcelable("conference", toAdd);
134 toSend.putExtra("resuming", false);
135 toSend.putExtras(bundle);
136 mService.startActivity(toSend);
137 mService.mMediaManager.startRing("");
138 mService.mMediaManager.obtainAudioFocus(true);
139 } catch (Exception e) {
140 e.printStackTrace();
141 }
142 }
143
144 @Override
145 public void callOnConferenceCreated(final String confID) {
146 Log.w(TAG, "CONFERENCE CREATED:" + confID);
147 Intent intent = new Intent(CONF_CREATED);
148 Conference created = new Conference(confID);
149
150 StringVect all_participants = Ringservice.sflph_call_get_participant_list(confID);
151 Log.w(TAG, "all_participants:" + all_participants.size());
152 for (int i = 0; i < all_participants.size(); ++i) {
153 if (mService.getConferences().get(all_participants.get(i)) != null) {
154 created.addParticipant(mService.getConferences().get(all_participants.get(i)).getCallById(all_participants.get(i)));
155 mService.getConferences().remove(all_participants.get(i));
156 } else {
157 for (Map.Entry<String, Conference> stringConferenceEntry : mService.getConferences().entrySet()) {
158 Conference tmp = stringConferenceEntry.getValue();
159 for (SipCall c : tmp.getParticipants()) {
160 if (c.getCallId().contentEquals(all_participants.get(i))) {
161 created.addParticipant(c);
162 mService.getConferences().get(tmp.getId()).removeParticipant(c);
163 }
164 }
165 }
166 }
167 }
168 intent.putExtra("conference", created);
169 intent.putExtra("confID", created.getId());
170 mService.getConferences().put(created.getId(), created);
171 mService.sendBroadcast(intent);
172 }
173
174 @Override
175 public void callOnIncomingMessage(String ID, String from, String msg) {
176 Log.w(TAG, "on_incoming_message:" + msg);
177 Intent intent = new Intent(INCOMING_TEXT);
178 intent.putExtra("CallID", ID);
179 intent.putExtra("From", from);
180 intent.putExtra("Msg", msg);
181
182 if (mService.getConferences().get(ID) != null) {
183 mService.getConferences().get(ID).addSipMessage(new SipMessage(true, msg));
184 intent.putExtra("conference", mService.getConferences().get(ID));
185 } else {
186 for (Map.Entry<String, Conference> stringConferenceEntry : mService.getConferences().entrySet()) {
187 Conference tmp = stringConferenceEntry.getValue();
188 for (SipCall c : tmp.getParticipants()) {
189 if (c.getCallId().contentEquals(ID)) {
190 mService.getConferences().get(tmp.getId()).addSipMessage(new SipMessage(true, msg));
191 intent.putExtra("conference", tmp);
192 }
193 }
194 }
195
196 }
197 mService.sendBroadcast(intent);
198 }
199
200 @Override
201 public void callOnConferenceRemove(String confID) {
202 Log.i(TAG, "on_conference_removed:");
203 Intent intent = new Intent(CONF_REMOVED);
204 intent.putExtra("confID", confID);
205
206 Conference toReInsert = mService.getConferences().get(confID);
207 for (SipCall call : toReInsert.getParticipants()) {
208 mService.getConferences().put(call.getCallId(), new Conference(call));
209 }
210 intent.putExtra("conference", mService.getConferences().get(confID));
211 mService.getConferences().remove(confID);
212 mService.sendBroadcast(intent);
213
214 }
215
216 @Override
217 public void callOnConferenceChanged(String confID, String state) {
218 Log.i(TAG, "on_conference_state_changed:");
219 Intent intent = new Intent(CONF_CHANGED);
220 intent.putExtra("confID", confID);
221 intent.putExtra("State", state);
222
223
224 Log.i(TAG, "Received:" + intent.getAction());
225 Log.i(TAG, "State:" + state);
226
227 Conference toModify = mService.getConferences().get(confID);
228 toModify.setCallState(confID, state);
229
230 ArrayList<String> newParticipants = SwigNativeConverter.convertSwigToNative(Ringservice.sflph_call_get_participant_list(intent.getStringExtra("confID")));
231
232 if (toModify.getParticipants().size() < newParticipants.size()) {
233 // We need to add the new participant to the conf
234 for (String newParticipant : newParticipants) {
235 if (toModify.getCallById(newParticipant) == null) {
236 mService.addCallToConference(toModify.getId(), newParticipant);
237 }
238 }
239 } else if (toModify.getParticipants().size() > newParticipants.size()) {
240 Log.i(TAG, "toModify.getParticipants().size() > newParticipants.size()");
241 for (SipCall participant : toModify.getParticipants()) {
242 if (!newParticipants.contains(participant.getCallId())) {
243 mService.detachCallFromConference(toModify.getId(), participant);
244 break;
245 }
246 }
247 }
248
249 mService.sendBroadcast(intent);
250 }
251
252 @Override
253 public void callOnRecordPlaybackFilepath(String id, String filename) {
254 Intent intent = new Intent();
255 intent.putExtra("callID", id);
256 intent.putExtra("file", filename);
257 mService.sendBroadcast(intent);
258 }
259
260 @Override
261 public void callOnSecureSdesOn(String callID) {
262 Log.i(TAG, "on_secure_sdes_on");
263 SecureSipCall call = (SecureSipCall) mService.getCallById(callID);
264 call.setInitialized();
265 call.useSecureSDES(true);
266 }
267
268 @Override
269 public void callOnSecureSdesOff(String callID) {
270 Log.i(TAG, "on_secure_sdes_off");
271 SecureSipCall call = (SecureSipCall) mService.getCallById(callID);
272 call.setInitialized();
273 call.useSecureSDES(false);
274 }
275
276 @Override
277 public void callOnSecureZrtpOn(String callID, String cipher) {
278 Log.i(TAG, "on_secure_zrtp_on");
279 Intent intent = new Intent(ZRTP_ON);
280 SecureSipCall call = (SecureSipCall) mService.getCallById(callID);
281 call.setInitialized();
282 call.setZrtpSupport(true);
283 intent.putExtra("callID", callID);
284 intent.putExtra("conference", mService.findConference(callID));
285 mService.sendBroadcast(intent);
286 }
287
288 @Override
289 public void callOnSecureZrtpOff(String callID) {
290 Log.i(TAG, "on_secure_zrtp_off");
291 Intent intent = new Intent(ZRTP_OFF);
292 intent.putExtra("callID", callID);
293 SecureSipCall call = (SecureSipCall) mService.getCallById(callID);
294 // Security can be off because call was hung up
295 if (call == null)
296 return;
297
298 call.setInitialized();
299 call.setZrtpSupport(false);
300 intent.putExtra("conference", mService.findConference(callID));
301 mService.sendBroadcast(intent);
302 }
303
304 @Override
305 public void callOnShowSas(String callID, String sas, int verified) {
306 Log.i(TAG, "on_show_sas:" + sas);
307 Intent intent = new Intent(DISPLAY_SAS);
308 SecureSipCall call = (SecureSipCall) mService.getCallById(callID);
309 call.setSAS(sas);
310 call.sasConfirmedByZrtpLayer(verified);
311
312 intent.putExtra("callID", callID);
313 intent.putExtra("SAS", sas);
314 intent.putExtra("verified", verified);
315 intent.putExtra("conference", mService.findConference(callID));
316 mService.sendBroadcast(intent);
317 }
318
319 @Override
320 public void callOnZrtpNotSuppOther(String callID) {
321 Log.i(TAG, "on_zrtp_not_supported");
322 Intent intent = new Intent(ZRTP_NOT_SUPPORTED);
323 SecureSipCall call = (SecureSipCall) mService.getCallById(callID);
324 call.setInitialized();
325 call.setZrtpSupport(false);
326 intent.putExtra("callID", callID);
327 intent.putExtra("conference", mService.findConference(callID));
328 mService.sendBroadcast(intent);
329 }
330
331 @Override
332 public void callOnZrtpNegotiationFail(String callID, String reason, String severity) {
333 Log.i(TAG, "on_zrtp_negociation_failed");
334 Intent intent = new Intent(ZRTP_NEGOTIATION_FAILED);
335 SecureSipCall call = (SecureSipCall) mService.getCallById(callID);
336 call.setInitialized();
337 call.setZrtpSupport(false);
338 intent.putExtra("callID", callID);
339 intent.putExtra("conference", mService.findConference(callID));
340 mService.sendBroadcast(intent);
341 }
342
343 @Override
344 public void callOnRtcpReceiveReport(String callID, IntegerMap stats) {
345 Log.i(TAG, "on_rtcp_report_received");
346 Intent intent = new Intent(RTCP_REPORT_RECEIVED);
347 mService.sendBroadcast(intent);
348 }
349
350}