blob: 60b43eeea86e032fb8a1319742e40c930870361a [file] [log] [blame]
Emeric Vigier6119d782012-09-21 18:04:14 -04001/**
2 * Copyright (C) 2010-2012 Regis Montoya (aka r3gis - www.r3gis.fr)
Alexandre Lisionc1024c02014-01-06 11:12:53 -05003 * Copyright (C) 2004-2014 Savoir-Faire Linux Inc.
Emeric Vigier6119d782012-09-21 18:04:14 -04004 *
5 * Author: Regis Montoya <r3gis.3R@gmail.com>
6 * Author: Emeric Vigier <emeric.vigier@savoirfairelinux.com>
alision11e8e162013-05-28 10:33:14 -04007 * Alexandre Lision <alexandre.lision@savoirfairelinux.com>
Emeric Vigier6119d782012-09-21 18:04:14 -04008 *
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 * If you own a pjsip commercial license you can also redistribute it
14 * and/or modify it under the terms of the GNU Lesser General Public License
15 * as an android library.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 */
Alexandre Lision064e1e02013-10-01 16:18:42 -040025package org.sflphone.service;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040026
Alexandre Lision96a1ef02014-09-03 15:28:08 -040027import android.os.Handler;
28
29import java.util.ArrayList;
30import java.util.HashMap;
31import java.util.Iterator;
32import java.util.List;
33import java.util.Map;
34import java.util.Map.Entry;
35
Alexandre Lisionfc91a462014-08-07 18:21:07 -040036import android.app.Service;
37import android.content.Intent;
38import android.os.*;
39import android.util.Log;
Alexandre Lision945e4612014-01-15 17:40:31 -050040import org.sflphone.history.HistoryManager;
Alexandre Lisiona7ab2e32014-02-14 15:33:33 -050041import org.sflphone.model.*;
Alexandre Lision6d867b92013-10-25 15:36:28 -040042import org.sflphone.utils.MediaManager;
Alexandre Lisione0045442013-10-25 09:16:19 -040043import org.sflphone.utils.SipNotifications;
Alexandre Lision2aae48d2013-12-04 13:50:38 -050044import org.sflphone.utils.SwigNativeConverter;
Alexandre Lision064e1e02013-10-01 16:18:42 -040045
Emeric Vigiereaf2c492012-09-19 14:38:20 -040046
Emeric Vigiereaf2c492012-09-19 14:38:20 -040047public class SipService extends Service {
48
49 static final String TAG = "SipService";
Emeric Vigier6119d782012-09-21 18:04:14 -040050 private SipServiceExecutor mExecutor;
51 private static HandlerThread executorThread;
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -050052
Alexandre Lision96a1ef02014-09-03 15:28:08 -040053 private Handler handler = new Handler();
54 private static int POLLING_TIMEOUT = 500;
55 private Runnable pollEvents = new Runnable() {
56 @Override
57 public void run() {
58 SFLPhoneservice.sflph_poll_events();
59 handler.postDelayed(this, POLLING_TIMEOUT);
60 }
61 };
Emeric Vigier6119d782012-09-21 18:04:14 -040062 private boolean isPjSipStackStarted = false;
alisioncc7bb422013-06-06 15:31:39 -040063
Alexandre Lision945e4612014-01-15 17:40:31 -050064 protected SipNotifications mNotificationManager;
65 protected HistoryManager mHistoryManager;
66 protected MediaManager mMediaManager;
Alexandre Lisione0045442013-10-25 09:16:19 -040067
Alexandre Lision945e4612014-01-15 17:40:31 -050068 private HashMap<String, Conference> mConferences = new HashMap<String, Conference>();
Alexandre Lision7b151702014-09-04 10:07:34 -040069 private ConfigurationManagerCallback configurationCallback;
70 private CallManagerCallBack callManagerCallBack;
Emeric Vigier6119d782012-09-21 18:04:14 -040071
Alexandre Lision945e4612014-01-15 17:40:31 -050072 public HashMap<String, Conference> getConferences() {
73 return mConferences;
alision806e18e2013-06-21 15:30:17 -040074 }
alision43a9b362013-05-01 16:30:15 -040075
Alexandre Lision183bf452014-01-17 11:21:59 -050076 public void addCallToConference(String confId, String callId) {
77 if(mConferences.get(callId) != null){
78 // We add a simple call to a conference
Alexandre Lision96db8032014-01-17 16:43:51 -050079 Log.i(TAG, "// We add a simple call to a conference");
Alexandre Lision183bf452014-01-17 11:21:59 -050080 mConferences.get(confId).addParticipant(mConferences.get(callId).getParticipants().get(0));
81 mConferences.remove(callId);
82 } else {
Alexandre Lision96db8032014-01-17 16:43:51 -050083 Log.i(TAG, "addCallToConference");
Alexandre Lisionfc91a462014-08-07 18:21:07 -040084 for (Entry<String, Conference> stringConferenceEntry : mConferences.entrySet()) {
85 Conference tmp = stringConferenceEntry.getValue();
Alexandre Lision183bf452014-01-17 11:21:59 -050086 for (SipCall c : tmp.getParticipants()) {
87 if (c.getCallId().contentEquals(callId)) {
88 mConferences.get(confId).addParticipant(c);
Alexandre Lision96db8032014-01-17 16:43:51 -050089 mConferences.get(tmp.getId()).removeParticipant(c);
Alexandre Lision183bf452014-01-17 11:21:59 -050090 }
91 }
92 }
93 }
Alexandre Lision183bf452014-01-17 11:21:59 -050094 }
95
Alexandre Lision96db8032014-01-17 16:43:51 -050096 public void detachCallFromConference(String confId, SipCall call) {
97 Log.i(TAG, "detachCallFromConference");
Alexandre Lision183bf452014-01-17 11:21:59 -050098 Conference separate = new Conference(call);
99 mConferences.put(separate.getId(), separate);
Alexandre Lision96db8032014-01-17 16:43:51 -0500100 mConferences.get(confId).removeParticipant(call);
Alexandre Lision183bf452014-01-17 11:21:59 -0500101 }
102
alision43a9b362013-05-01 16:30:15 -0400103 @Override
104 public boolean onUnbind(Intent i) {
105 super.onUnbind(i);
106 Log.i(TAG, "onUnbind(intent)");
Alexandre Lision0f550ee2013-10-25 15:34:38 -0400107 return true;
108 }
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400109
Alexandre Lision0f550ee2013-10-25 15:34:38 -0400110 @Override
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400111 public void onRebind(Intent i) {
Alexandre Lision0f550ee2013-10-25 15:34:38 -0400112 super.onRebind(i);
alision43a9b362013-05-01 16:30:15 -0400113 }
114
115 /* called once by startService() */
116 @Override
117 public void onCreate() {
118 Log.i(TAG, "onCreated");
119 super.onCreate();
120
alisioncc7bb422013-06-06 15:31:39 -0400121 getExecutor().execute(new StartRunnable());
Alexandre Lisione0045442013-10-25 09:16:19 -0400122
Alexandre Lision945e4612014-01-15 17:40:31 -0500123 mNotificationManager = new SipNotifications(this);
124 mMediaManager = new MediaManager(this);
125 mHistoryManager = new HistoryManager(this);
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400126
Alexandre Lision945e4612014-01-15 17:40:31 -0500127 mNotificationManager.onServiceCreate();
128 mMediaManager.startService();
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400129
alisioncc7bb422013-06-06 15:31:39 -0400130 }
alision43a9b362013-05-01 16:30:15 -0400131
132 /* called for each startService() */
133 @Override
134 public int onStartCommand(Intent intent, int flags, int startId) {
135 Log.i(TAG, "onStarted");
136 super.onStartCommand(intent, flags, startId);
Alexandre Lision0f550ee2013-10-25 15:34:38 -0400137 return START_STICKY; /* started and stopped explicitly */
alision43a9b362013-05-01 16:30:15 -0400138 }
139
140 @Override
141 public void onDestroy() {
Alexandre Lision52214992013-10-28 17:41:23 -0400142 Log.i(TAG, "onDestroy");
alision43a9b362013-05-01 16:30:15 -0400143 /* called once by stopService() */
Alexandre Lision945e4612014-01-15 17:40:31 -0500144 mNotificationManager.onServiceDestroy();
Alexandre Lision183bf452014-01-17 11:21:59 -0500145 mMediaManager.stopService();
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400146 getExecutor().execute(new FinalizeRunnable());
alision43a9b362013-05-01 16:30:15 -0400147 super.onDestroy();
148
alision43a9b362013-05-01 16:30:15 -0400149 }
150
151 @Override
152 public IBinder onBind(Intent arg0) {
153 Log.i(TAG, "onBound");
154 return mBinder;
155 }
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400156
alision43a9b362013-05-01 16:30:15 -0400157 private static Looper createLooper() {
158 if (executorThread == null) {
159 Log.d(TAG, "Creating new handler thread");
160 // ADT gives a fake warning due to bad parse rule.
161 executorThread = new HandlerThread("SipService.Executor");
162 executorThread.start();
163 }
164 return executorThread.getLooper();
165 }
166
167 public SipServiceExecutor getExecutor() {
168 // create mExecutor lazily
169 if (mExecutor == null) {
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500170 mExecutor = new SipServiceExecutor();
alision43a9b362013-05-01 16:30:15 -0400171 }
172 return mExecutor;
173 }
174
Alexandre Lision5f144b82014-02-11 09:59:36 -0500175 public SipCall getCallById(String callID) {
176 if (getConferences().get(callID) != null) {
177 return getConferences().get(callID).getCallById(callID);
178 } else {
179 // Check if call is in a conference
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400180 for (Entry<String, Conference> stringConferenceEntry : getConferences().entrySet()) {
181 Conference tmp = stringConferenceEntry.getValue();
Alexandre Lision5f144b82014-02-11 09:59:36 -0500182 SipCall c = tmp.getCallById(callID);
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400183 if (c != null)
184 return c;
Alexandre Lision5f144b82014-02-11 09:59:36 -0500185 }
186 }
187 return null;
188 }
189
alision43a9b362013-05-01 16:30:15 -0400190 // Executes immediate tasks in a single executorThread.
191 public static class SipServiceExecutor extends Handler {
alision43a9b362013-05-01 16:30:15 -0400192
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500193 SipServiceExecutor() {
alision43a9b362013-05-01 16:30:15 -0400194 super(createLooper());
alision43a9b362013-05-01 16:30:15 -0400195 }
196
197 public void execute(Runnable task) {
198 // TODO: add wakelock
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500199 Message.obtain(SipServiceExecutor.this, 0/* don't care */, task).sendToTarget();
Alexandre Lisioncdec5952013-07-17 14:18:22 -0400200 Log.w(TAG, "SenT!");
alision43a9b362013-05-01 16:30:15 -0400201 }
202
203 @Override
204 public void handleMessage(Message msg) {
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500205 Log.w(TAG, "handleMessage");
alision43a9b362013-05-01 16:30:15 -0400206 if (msg.obj instanceof Runnable) {
207 executeInternal((Runnable) msg.obj);
208 } else {
209 Log.w(TAG, "can't handle msg: " + msg);
210 }
211 }
212
213 private void executeInternal(Runnable task) {
214 try {
215 task.run();
216 } catch (Throwable t) {
217 Log.e(TAG, "run task: " + task, t);
218 }
219 }
220 }
Alexandre Lision63870a72013-10-28 16:33:47 -0400221
222 private void stopDaemon() {
Alexandre Lision96a1ef02014-09-03 15:28:08 -0400223 handler.removeCallbacks(pollEvents);
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400224 SFLPhoneservice.sflph_fini();
225 isPjSipStackStarted = false;
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400226 }
alision43a9b362013-05-01 16:30:15 -0400227
228 private void startPjSipStack() throws SameThreadException {
229 if (isPjSipStackStarted)
230 return;
231
232 try {
233 System.loadLibrary("gnustl_shared");
alision43a9b362013-05-01 16:30:15 -0400234 System.loadLibrary("crypto");
235 System.loadLibrary("ssl");
Alexandre Lision399db752014-09-03 10:27:56 -0400236 System.loadLibrary("codec_ulaw");
237 System.loadLibrary("codec_alaw");
238 System.loadLibrary("codec_speex_nb");
239 System.loadLibrary("codec_speex_ub");
240 System.loadLibrary("codec_speex_wb");
241 System.loadLibrary("codec_g729");
242 System.loadLibrary("codec_gsm");
243 System.loadLibrary("codec_opus");
244 System.loadLibrary("sflphonejni");
alision43a9b362013-05-01 16:30:15 -0400245 isPjSipStackStarted = true;
Adrien Béraud9360f242013-09-19 11:07:42 +1000246
alision43a9b362013-05-01 16:30:15 -0400247 } catch (UnsatisfiedLinkError e) {
248 Log.e(TAG, "Problem with the current Pj stack...", e);
249 isPjSipStackStarted = false;
250 return;
251 } catch (Exception e) {
252 Log.e(TAG, "Problem with the current Pj stack...", e);
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400253 isPjSipStackStarted = false;
alision43a9b362013-05-01 16:30:15 -0400254 }
255
Alexandre Lision7b151702014-09-04 10:07:34 -0400256 configurationCallback = new ConfigurationManagerCallback(this);
257 callManagerCallBack = new CallManagerCallBack(this);
258 SFLPhoneservice.init(configurationCallback, callManagerCallBack);
Alexandre Lision96a1ef02014-09-03 15:28:08 -0400259 handler.postDelayed(pollEvents, POLLING_TIMEOUT);
260 Log.i(TAG, "PjSIPStack started");
alision43a9b362013-05-01 16:30:15 -0400261 }
262
263 // Enforce same thread contract to ensure we do not call from somewhere else
264 public class SameThreadException extends Exception {
265 private static final long serialVersionUID = -905639124232613768L;
266
267 public SameThreadException() {
268 super("Should be launched from a single worker thread");
269 }
270 }
271
272 public abstract static class SipRunnable implements Runnable {
273 protected abstract void doRun() throws SameThreadException, RemoteException;
274
Adrien Béraud9360f242013-09-19 11:07:42 +1000275 @Override
alision43a9b362013-05-01 16:30:15 -0400276 public void run() {
277 try {
278 doRun();
279 } catch (SameThreadException e) {
280 Log.e(TAG, "Not done from same thread");
281 } catch (RemoteException e) {
282 Log.e(TAG, e.toString());
283 }
284 }
285 }
286
Alexandre Lisionfab23f82013-11-01 11:22:30 -0400287 public abstract class SipRunnableWithReturn implements Runnable {
alision43a9b362013-05-01 16:30:15 -0400288 Object obj = null;
289 boolean done = false;
290
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500291 protected abstract Object doRun() throws SameThreadException, RemoteException;
alision43a9b362013-05-01 16:30:15 -0400292
293 public Object getVal() {
294 return obj;
295 }
296
297 public boolean isDone() {
298 return done;
299 }
300
Adrien Béraud9360f242013-09-19 11:07:42 +1000301 @Override
alision43a9b362013-05-01 16:30:15 -0400302 public void run() {
303 try {
Alexandre Lision35577132013-12-06 15:21:15 -0500304 if (isPjSipStackStarted)
Alexandre Lisionfab23f82013-11-01 11:22:30 -0400305 obj = doRun();
alision43a9b362013-05-01 16:30:15 -0400306 done = true;
307 } catch (SameThreadException e) {
308 Log.e(TAG, "Not done from same thread");
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500309 } catch (RemoteException e) {
310 Log.e(TAG, e.toString());
alision43a9b362013-05-01 16:30:15 -0400311 }
312 }
313 }
314
315 class StartRunnable extends SipRunnable {
316 @Override
317 protected void doRun() throws SameThreadException {
318 startPjSipStack();
319 }
320 }
Alexandre Lision63870a72013-10-28 16:33:47 -0400321
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400322 class FinalizeRunnable extends SipRunnable {
323 @Override
324 protected void doRun() throws SameThreadException {
325 stopDaemon();
326 }
327 }
alision43a9b362013-05-01 16:30:15 -0400328
alision43a9b362013-05-01 16:30:15 -0400329 /* ************************************
Alexandre Lision9abb7c92014-08-04 19:22:55 -0400330 *
alision43a9b362013-05-01 16:30:15 -0400331 * Implement public interface for the service
Alexandre Lision9abb7c92014-08-04 19:22:55 -0400332 *
Alexandre Lision67817192013-07-18 12:04:30 -0400333 * *********************************
334 */
335
Emeric Vigier6119d782012-09-21 18:04:14 -0400336 private final ISipService.Stub mBinder = new ISipService.Stub() {
337
338 @Override
alisionfde875f2013-05-28 17:01:54 -0400339 public void placeCall(final SipCall call) {
Alexandre Lisiona7ab2e32014-02-14 15:33:33 -0500340
Emeric Vigier6119d782012-09-21 18:04:14 -0400341 getExecutor().execute(new SipRunnable() {
342 @Override
343 protected void doRun() throws SameThreadException {
344 Log.i(TAG, "SipService.placeCall() thread running...");
Alexandre Lision651b5262014-02-21 17:14:14 -0500345 Conference toAdd;
346 if(call.getAccount().useSecureLayer()){
Alexandre Lision2cd17d32014-02-27 15:57:20 -0500347 SecureSipCall secureCall = new SecureSipCall(call);
Alexandre Lision651b5262014-02-21 17:14:14 -0500348 toAdd = new Conference(secureCall);
349 } else {
350 toAdd = new Conference(call);
351 }
Alexandre Lision945e4612014-01-15 17:40:31 -0500352 mConferences.put(toAdd.getId(), toAdd);
353 mMediaManager.obtainAudioFocus(false);
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400354 SFLPhoneservice.sflph_call_place(call.getAccount().getAccountID(), call.getCallId(), call.getmContact().getPhones().get(0).getNumber());
Emeric Vigier6119d782012-09-21 18:04:14 -0400355 }
356 });
357 }
358
359 @Override
360 public void refuse(final String callID) {
Alexandre Lisionf02190d2013-12-12 17:26:12 -0500361
Emeric Vigier6119d782012-09-21 18:04:14 -0400362 getExecutor().execute(new SipRunnable() {
363 @Override
364 protected void doRun() throws SameThreadException {
365 Log.i(TAG, "SipService.refuse() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400366 SFLPhoneservice.sflph_call_refuse(callID);
Emeric Vigier6119d782012-09-21 18:04:14 -0400367 }
368 });
369 }
370
371 @Override
372 public void accept(final String callID) {
Alexandre Lision945e4612014-01-15 17:40:31 -0500373 mMediaManager.stopRing();
Emeric Vigier6119d782012-09-21 18:04:14 -0400374 getExecutor().execute(new SipRunnable() {
375 @Override
376 protected void doRun() throws SameThreadException {
Tristan Matthews40cf25e2013-07-24 13:45:15 -0400377 Log.i(TAG, "SipService.accept() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400378 SFLPhoneservice.sflph_call_accept(callID);
Alexandre Lision945e4612014-01-15 17:40:31 -0500379 mMediaManager.RouteToInternalSpeaker();
Emeric Vigier6119d782012-09-21 18:04:14 -0400380 }
381 });
382 }
383
384 @Override
385 public void hangUp(final String callID) {
Alexandre Lision945e4612014-01-15 17:40:31 -0500386 mMediaManager.stopRing();
Alexandre Lision2cd17d32014-02-27 15:57:20 -0500387 Log.e(TAG, "HANGING UP");
Emeric Vigier6119d782012-09-21 18:04:14 -0400388 getExecutor().execute(new SipRunnable() {
389 @Override
390 protected void doRun() throws SameThreadException {
391 Log.i(TAG, "SipService.hangUp() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400392 SFLPhoneservice.sflph_call_hang_up(callID);
Alexandre Lision3c37dca2014-02-21 14:13:26 -0500393 removeCall(callID);
Alexandre Lision3c37dca2014-02-21 14:13:26 -0500394 if(mConferences.size() == 0) {
395 Log.i(TAG, "No more calls!");
Alexandre Lision183bf452014-01-17 11:21:59 -0500396 mMediaManager.abandonAudioFocus();
Alexandre Lision3c37dca2014-02-21 14:13:26 -0500397 }
Emeric Vigier6119d782012-09-21 18:04:14 -0400398 }
399 });
400 }
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400401
402 @Override
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400403 public void hold(final String callID) {
404 getExecutor().execute(new SipRunnable() {
405 @Override
406 protected void doRun() throws SameThreadException {
407 Log.i(TAG, "SipService.hold() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400408 SFLPhoneservice.sflph_call_hold(callID);
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400409 }
410 });
411 }
412
413 @Override
414 public void unhold(final String callID) {
415 getExecutor().execute(new SipRunnable() {
416 @Override
417 protected void doRun() throws SameThreadException {
418 Log.i(TAG, "SipService.unhold() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400419 SFLPhoneservice.sflph_call_unhold(callID);
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400420 }
421 });
422 }
Adrien Béraud9360f242013-09-19 11:07:42 +1000423
Alexandre Lision6711ab22013-09-16 15:15:38 -0400424 @Override
425 public HashMap<String, String> getCallDetails(String callID) throws RemoteException {
426 class CallDetails extends SipRunnableWithReturn {
427 private String id;
428
429 CallDetails(String callID) {
430 id = callID;
431 }
432
433 @Override
434 protected StringMap doRun() throws SameThreadException {
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400435 Log.i(TAG, "SipService.getCallDetails() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400436 return SFLPhoneservice.sflph_call_get_call_details(id);
Alexandre Lision6711ab22013-09-16 15:15:38 -0400437 }
438 }
439
440 CallDetails runInstance = new CallDetails(callID);
441 getExecutor().execute(runInstance);
442
443 while (!runInstance.isDone()) {
444 }
445 StringMap swigmap = (StringMap) runInstance.getVal();
446
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400447 return SwigNativeConverter.convertCallDetailsToNative(swigmap);
Alexandre Lision6711ab22013-09-16 15:15:38 -0400448 }
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400449
450 @Override
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400451 public void setAudioPlugin(final String audioPlugin) {
452 getExecutor().execute(new SipRunnable() {
alision371b77e2013-04-23 14:51:26 -0400453 @Override
454 protected void doRun() throws SameThreadException {
455 Log.i(TAG, "SipService.setAudioPlugin() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400456 SFLPhoneservice.sflph_config_set_audio_plugin(audioPlugin);
alision371b77e2013-04-23 14:51:26 -0400457 }
Alexandre Savard31d27c62012-10-04 16:05:08 -0400458 });
459 }
460
461 @Override
462 public String getCurrentAudioOutputPlugin() {
463 class CurrentAudioPlugin extends SipRunnableWithReturn {
464 @Override
465 protected String doRun() throws SameThreadException {
466 Log.i(TAG, "SipService.getCurrentAudioOutputPlugin() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400467 return SFLPhoneservice.sflph_config_get_current_audio_output_plugin();
Alexandre Savard31d27c62012-10-04 16:05:08 -0400468 }
alision371b77e2013-04-23 14:51:26 -0400469 }
Alexandre Lision96a1ef02014-09-03 15:28:08 -0400470
Alexandre Savard31d27c62012-10-04 16:05:08 -0400471 CurrentAudioPlugin runInstance = new CurrentAudioPlugin();
472 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400473 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400474 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400475 }
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400476 return (String) runInstance.getVal();
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400477 }
Alexandre Savard713a34d2012-09-26 15:50:41 -0400478
479 @Override
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400480 public ArrayList<String> getAccountList() {
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400481 class AccountList extends SipRunnableWithReturn {
482 @Override
483 protected StringVect doRun() throws SameThreadException {
484 Log.i(TAG, "SipService.getAccountList() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400485 return SFLPhoneservice.sflph_config_get_account_list();
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400486 }
alision371b77e2013-04-23 14:51:26 -0400487 }
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400488 AccountList runInstance = new AccountList();
489 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400490 while (!runInstance.isDone()) {
491 }
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400492 StringVect swigvect = (StringVect) runInstance.getVal();
493
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400494 ArrayList<String> nativelist = new ArrayList<String>();
Alexandre Savard52a72522012-09-27 16:40:13 -0400495
alision371b77e2013-04-23 14:51:26 -0400496 for (int i = 0; i < swigvect.size(); i++)
497 nativelist.add(swigvect.get(i));
Alexandre Savard52a72522012-09-27 16:40:13 -0400498
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400499 return nativelist;
alision371b77e2013-04-23 14:51:26 -0400500 }
Alexandre Lision4b4233a2013-10-16 17:24:17 -0400501
Alexandre Lision4cf78702013-10-16 13:43:23 -0400502 @Override
Alexandre Lision4b4233a2013-10-16 17:24:17 -0400503 public void setAccountOrder(final String order) {
Alexandre Lision4cf78702013-10-16 13:43:23 -0400504 getExecutor().execute(new SipRunnable() {
505 @Override
506 protected void doRun() throws SameThreadException {
507 Log.i(TAG, "SipService.setAccountsOrder() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400508 SFLPhoneservice.sflph_config_set_accounts_order(order);
Alexandre Lision4cf78702013-10-16 13:43:23 -0400509 }
510 });
511 }
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400512
513 @Override
alision371b77e2013-04-23 14:51:26 -0400514 public HashMap<String, String> getAccountDetails(final String accountID) {
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400515 class AccountDetails extends SipRunnableWithReturn {
516 private String id;
alision371b77e2013-04-23 14:51:26 -0400517
518 AccountDetails(String accountId) {
519 id = accountId;
520 }
521
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400522 @Override
523 protected StringMap doRun() throws SameThreadException {
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400524 Log.i(TAG, "SipService.getAccountDetails() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400525 return SFLPhoneservice.sflph_config_get_account_details(id);
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400526 }
alision371b77e2013-04-23 14:51:26 -0400527 }
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400528
529 AccountDetails runInstance = new AccountDetails(accountID);
530 getExecutor().execute(runInstance);
alisionfde875f2013-05-28 17:01:54 -0400531
alision371b77e2013-04-23 14:51:26 -0400532 while (!runInstance.isDone()) {
533 }
534 StringMap swigmap = (StringMap) runInstance.getVal();
Alexandre Savard713a34d2012-09-26 15:50:41 -0400535
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400536 return SwigNativeConverter.convertAccountToNative(swigmap);
Alexandre Savard713a34d2012-09-26 15:50:41 -0400537 }
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400538
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400539 @SuppressWarnings("unchecked")
540 // Hashmap runtime cast
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400541 @Override
alisioncc7bb422013-06-06 15:31:39 -0400542 public void setAccountDetails(final String accountId, final Map map) {
alision371b77e2013-04-23 14:51:26 -0400543 HashMap<String, String> nativemap = (HashMap<String, String>) map;
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400544
Alexandre Lision2aae48d2013-12-04 13:50:38 -0500545 final StringMap swigmap = SwigNativeConverter.convertFromNativeToSwig(nativemap);
Alexandre Savard718d49f2012-10-02 15:17:13 -0400546
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400547 getExecutor().execute(new SipRunnable() {
548 @Override
549 protected void doRun() throws SameThreadException {
alisioncc7bb422013-06-06 15:31:39 -0400550
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400551 SFLPhoneservice.sflph_config_set_account_details(accountId, swigmap);
alisioncc7bb422013-06-06 15:31:39 -0400552 Log.i(TAG, "SipService.setAccountDetails() thread running...");
553 }
554
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400555 });
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400556 }
557
Alexandre Lision451f2a82013-11-12 12:55:55 -0500558 @Override
559 public Map getAccountTemplate() throws RemoteException {
560 class AccountTemplate extends SipRunnableWithReturn {
561
562 @Override
563 protected StringMap doRun() throws SameThreadException {
564 Log.i(TAG, "SipService.getAccountTemplate() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400565 return SFLPhoneservice.sflph_config_get_account_template();
Alexandre Lision451f2a82013-11-12 12:55:55 -0500566 }
567 }
568
569 AccountTemplate runInstance = new AccountTemplate();
570 getExecutor().execute(runInstance);
571
572 while (!runInstance.isDone()) {
573 }
574 StringMap swigmap = (StringMap) runInstance.getVal();
575
Alexandre Lision96a1ef02014-09-03 15:28:08 -0400576 return SwigNativeConverter.convertAccountToNative(swigmap);
Alexandre Lision451f2a82013-11-12 12:55:55 -0500577 }
alisioncc7bb422013-06-06 15:31:39 -0400578
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400579 @SuppressWarnings("unchecked")
580 // Hashmap runtime cast
Alexandre Savard46036572012-10-05 13:56:49 -0400581 @Override
582 public String addAccount(Map map) {
583 class AddAccount extends SipRunnableWithReturn {
584 StringMap map;
alision371b77e2013-04-23 14:51:26 -0400585
586 AddAccount(StringMap m) {
587 map = m;
588 }
589
Alexandre Savard46036572012-10-05 13:56:49 -0400590 @Override
591 protected String doRun() throws SameThreadException {
Alexandre Lisionc8397da2014-04-16 15:03:22 -0400592 Log.i(TAG, "SipService.addAccount() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400593 return SFLPhoneservice.sflph_config_add_account(map);
Alexandre Savard46036572012-10-05 13:56:49 -0400594 }
alision371b77e2013-04-23 14:51:26 -0400595 }
Alexandre Savard46036572012-10-05 13:56:49 -0400596
Alexandre Lision2aae48d2013-12-04 13:50:38 -0500597 final StringMap swigmap = SwigNativeConverter.convertFromNativeToSwig((HashMap<String, String>) map);
Alexandre Savard46036572012-10-05 13:56:49 -0400598
599 AddAccount runInstance = new AddAccount(swigmap);
600 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400601 while (!runInstance.isDone()) {
602 }
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400603 return (String) runInstance.getVal();
Alexandre Savard46036572012-10-05 13:56:49 -0400604 }
605
606 @Override
607 public void removeAccount(final String accountId) {
608 getExecutor().execute(new SipRunnable() {
609 @Override
610 protected void doRun() throws SameThreadException {
611 Log.i(TAG, "SipService.setAccountDetails() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400612 SFLPhoneservice.sflph_config_remove_account(accountId);
Alexandre Savard46036572012-10-05 13:56:49 -0400613 }
614 });
615 }
alision5f899632013-04-22 17:26:56 -0400616
alision43a9b362013-05-01 16:30:15 -0400617 /*************************
618 * Transfer related API
619 *************************/
620
alision7f18fc82013-05-01 09:37:33 -0400621 @Override
622 public void transfer(final String callID, final String to) throws RemoteException {
623 getExecutor().execute(new SipRunnable() {
624 @Override
625 protected void doRun() throws SameThreadException, RemoteException {
626 Log.i(TAG, "SipService.transfer() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400627 if (SFLPhoneservice.sflph_call_transfer(callID, to)) {
alision7f18fc82013-05-01 09:37:33 -0400628 Bundle bundle = new Bundle();
629 bundle.putString("CallID", callID);
630 bundle.putString("State", "HUNGUP");
631 Intent intent = new Intent(CallManagerCallBack.CALL_STATE_CHANGED);
alision7f18fc82013-05-01 09:37:33 -0400632 intent.putExtra("com.savoirfairelinux.sflphone.service.newstate", bundle);
alision84813a12013-05-27 17:40:39 -0400633 sendBroadcast(intent);
alision7f18fc82013-05-01 09:37:33 -0400634 } else
635 Log.i(TAG, "NOT OK");
636 }
637 });
638
639 }
alision43a9b362013-05-01 16:30:15 -0400640
alision7f18fc82013-05-01 09:37:33 -0400641 @Override
642 public void attendedTransfer(final String transferID, final String targetID) throws RemoteException {
643 getExecutor().execute(new SipRunnable() {
644 @Override
645 protected void doRun() throws SameThreadException, RemoteException {
alision43a9b362013-05-01 16:30:15 -0400646 Log.i(TAG, "SipService.attendedTransfer() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400647 if (SFLPhoneservice.sflph_call_attended_transfer(transferID, targetID)) {
alision7f18fc82013-05-01 09:37:33 -0400648 Log.i(TAG, "OK");
alision7f18fc82013-05-01 09:37:33 -0400649 } else
650 Log.i(TAG, "NOT OK");
651 }
652 });
alision43a9b362013-05-01 16:30:15 -0400653
654 }
655
656 /*************************
657 * Conference related API
658 *************************/
659
660 @Override
661 public void removeConference(final String confID) throws RemoteException {
662 getExecutor().execute(new SipRunnable() {
663 @Override
664 protected void doRun() throws SameThreadException, RemoteException {
665 Log.i(TAG, "SipService.createConference() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400666 SFLPhoneservice.sflph_call_remove_conference(confID);
alision43a9b362013-05-01 16:30:15 -0400667 }
668 });
669
alision7f18fc82013-05-01 09:37:33 -0400670 }
671
672 @Override
alision43a9b362013-05-01 16:30:15 -0400673 public void joinParticipant(final String sel_callID, final String drag_callID) throws RemoteException {
674 getExecutor().execute(new SipRunnable() {
675 @Override
676 protected void doRun() throws SameThreadException, RemoteException {
677 Log.i(TAG, "SipService.joinParticipant() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400678 SFLPhoneservice.sflph_call_join_participant(sel_callID, drag_callID);
alision806e18e2013-06-21 15:30:17 -0400679 // Generate a CONF_CREATED callback
alision43a9b362013-05-01 16:30:15 -0400680 }
681 });
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500682 Log.i(TAG, "After joining participants");
alision7f18fc82013-05-01 09:37:33 -0400683 }
684
alision7f18fc82013-05-01 09:37:33 -0400685 @Override
alision806e18e2013-06-21 15:30:17 -0400686 public void addParticipant(final SipCall call, final String confID) throws RemoteException {
alision43a9b362013-05-01 16:30:15 -0400687 getExecutor().execute(new SipRunnable() {
688 @Override
689 protected void doRun() throws SameThreadException, RemoteException {
690 Log.i(TAG, "SipService.addParticipant() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400691 SFLPhoneservice.sflph_call_add_participant(call.getCallId(), confID);
Alexandre Lision945e4612014-01-15 17:40:31 -0500692 mConferences.get(confID).getParticipants().add(call);
alision43a9b362013-05-01 16:30:15 -0400693 }
694 });
695
alision7f18fc82013-05-01 09:37:33 -0400696 }
697
698 @Override
alision43a9b362013-05-01 16:30:15 -0400699 public void addMainParticipant(final String confID) throws RemoteException {
700 getExecutor().execute(new SipRunnable() {
701 @Override
702 protected void doRun() throws SameThreadException, RemoteException {
703 Log.i(TAG, "SipService.addMainParticipant() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400704 SFLPhoneservice.sflph_call_add_main_participant(confID);
alision43a9b362013-05-01 16:30:15 -0400705 }
706 });
707
alision7f18fc82013-05-01 09:37:33 -0400708 }
709
710 @Override
alision43a9b362013-05-01 16:30:15 -0400711 public void detachParticipant(final String callID) throws RemoteException {
712 getExecutor().execute(new SipRunnable() {
713 @Override
714 protected void doRun() throws SameThreadException, RemoteException {
715 Log.i(TAG, "SipService.detachParticipant() thread running...");
alision806e18e2013-06-21 15:30:17 -0400716 Log.i(TAG, "Detaching " + callID);
Alexandre Lision945e4612014-01-15 17:40:31 -0500717 Iterator<Entry<String, Conference>> it = mConferences.entrySet().iterator();
718 Log.i(TAG, "mConferences size " + mConferences.size());
alision806e18e2013-06-21 15:30:17 -0400719 while (it.hasNext()) {
720 Conference tmp = it.next().getValue();
721 Log.i(TAG, "conf has " + tmp.getParticipants().size() + " participants");
722 if (tmp.contains(callID)) {
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500723 Conference toDetach = new Conference(tmp.getCallById(callID));
Alexandre Lision945e4612014-01-15 17:40:31 -0500724 mConferences.put(toDetach.getId(), toDetach);
alision806e18e2013-06-21 15:30:17 -0400725 Log.i(TAG, "Call found and put in current_calls");
726 }
727 }
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400728 SFLPhoneservice.sflph_call_detach_participant(callID);
alision43a9b362013-05-01 16:30:15 -0400729 }
730 });
731
alision7f18fc82013-05-01 09:37:33 -0400732 }
733
734 @Override
alision43a9b362013-05-01 16:30:15 -0400735 public void joinConference(final String sel_confID, final String drag_confID) throws RemoteException {
736 getExecutor().execute(new SipRunnable() {
737 @Override
738 protected void doRun() throws SameThreadException, RemoteException {
739 Log.i(TAG, "SipService.joinConference() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400740 SFLPhoneservice.sflph_call_join_conference(sel_confID, drag_confID);
alision43a9b362013-05-01 16:30:15 -0400741 }
742 });
743
alision7f18fc82013-05-01 09:37:33 -0400744 }
745
746 @Override
alision43a9b362013-05-01 16:30:15 -0400747 public void hangUpConference(final String confID) throws RemoteException {
Alexandre Lision2cd17d32014-02-27 15:57:20 -0500748 Log.e(TAG, "HANGING UP CONF");
alision43a9b362013-05-01 16:30:15 -0400749 getExecutor().execute(new SipRunnable() {
750 @Override
751 protected void doRun() throws SameThreadException, RemoteException {
752 Log.i(TAG, "SipService.joinConference() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400753 SFLPhoneservice.sflph_call_hang_up_conference(confID);
alision43a9b362013-05-01 16:30:15 -0400754 }
755 });
756
alision7f18fc82013-05-01 09:37:33 -0400757 }
758
759 @Override
alision43a9b362013-05-01 16:30:15 -0400760 public void holdConference(final String confID) throws RemoteException {
761 getExecutor().execute(new SipRunnable() {
762 @Override
763 protected void doRun() throws SameThreadException, RemoteException {
764 Log.i(TAG, "SipService.holdConference() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400765 SFLPhoneservice.sflph_call_hold_conference(confID);
alision43a9b362013-05-01 16:30:15 -0400766 }
767 });
768
alision7f18fc82013-05-01 09:37:33 -0400769 }
770
771 @Override
alision43a9b362013-05-01 16:30:15 -0400772 public void unholdConference(final String confID) throws RemoteException {
773 getExecutor().execute(new SipRunnable() {
774 @Override
775 protected void doRun() throws SameThreadException, RemoteException {
776 Log.i(TAG, "SipService.unholdConference() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400777 SFLPhoneservice.sflph_call_unhold_conference(confID);
alision43a9b362013-05-01 16:30:15 -0400778 }
779 });
780
alision7f18fc82013-05-01 09:37:33 -0400781 }
Alexandre Lision67817192013-07-18 12:04:30 -0400782
alisioncd8fb912013-06-28 14:43:51 -0400783 @Override
784 public boolean isConferenceParticipant(final String callID) throws RemoteException {
785 class IsParticipant extends SipRunnableWithReturn {
786
787 @Override
788 protected Boolean doRun() throws SameThreadException {
789 Log.i(TAG, "SipService.isRecording() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400790 return SFLPhoneservice.sflph_call_is_conference_participant(callID);
alisioncd8fb912013-06-28 14:43:51 -0400791 }
792 }
793
794 IsParticipant runInstance = new IsParticipant();
795 getExecutor().execute(runInstance);
796 while (!runInstance.isDone()) {
797 }
798
799 return (Boolean) runInstance.getVal();
800 }
alision7f18fc82013-05-01 09:37:33 -0400801
802 @Override
alisiondf1dac92013-06-27 17:35:53 -0400803 public HashMap<String, Conference> getConferenceList() throws RemoteException {
Alexandre Lision67817192013-07-18 12:04:30 -0400804 // class ConfList extends SipRunnableWithReturn {
805 // @Override
806 // protected StringVect doRun() throws SameThreadException {
807 // Log.i(TAG, "SipService.getConferenceList() thread running...");
808 // return callManagerJNI.getConferenceList();
809 // }
810 // }
811 // ;
812 // ConfList runInstance = new ConfList();
813 // getExecutor().execute(runInstance);
814 // while (!runInstance.isDone()) {
815 // // Log.w(TAG, "Waiting for getConferenceList");
816 // }
817 // StringVect swigvect = (StringVect) runInstance.getVal();
818 //
819 // ArrayList<String> nativelist = new ArrayList<String>();
820 //
821 // for (int i = 0; i < swigvect.size(); i++)
822 // nativelist.add(swigvect.get(i));
823 //
824 // return nativelist;
Alexandre Lision945e4612014-01-15 17:40:31 -0500825 return mConferences;
alision7f18fc82013-05-01 09:37:33 -0400826 }
827
828 @Override
alision907bde72013-06-20 14:40:37 -0400829 public List getParticipantList(final String confID) throws RemoteException {
830 class PartList extends SipRunnableWithReturn {
831 @Override
832 protected StringVect doRun() throws SameThreadException {
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500833 Log.i(TAG, "SipService.getParticipantList() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400834 return SFLPhoneservice.sflph_call_get_participant_list(confID);
alision907bde72013-06-20 14:40:37 -0400835 }
836 }
837 ;
838 PartList runInstance = new PartList();
839 getExecutor().execute(runInstance);
840 while (!runInstance.isDone()) {
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500841 Log.w(TAG, "getParticipantList");
alision907bde72013-06-20 14:40:37 -0400842 }
843 StringVect swigvect = (StringVect) runInstance.getVal();
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500844 Log.w(TAG, "After that");
alision907bde72013-06-20 14:40:37 -0400845 ArrayList<String> nativelist = new ArrayList<String>();
846
847 for (int i = 0; i < swigvect.size(); i++)
848 nativelist.add(swigvect.get(i));
849
850 return nativelist;
alision7f18fc82013-05-01 09:37:33 -0400851 }
alision806e18e2013-06-21 15:30:17 -0400852
alision1005ba12013-06-19 13:52:44 -0400853 @Override
alision7f18fc82013-05-01 09:37:33 -0400854 public String getConferenceId(String callID) throws RemoteException {
alision43a9b362013-05-01 16:30:15 -0400855 Log.e(TAG, "getConferenceList not implemented");
alision7f18fc82013-05-01 09:37:33 -0400856 return null;
857 }
858
859 @Override
alision806e18e2013-06-21 15:30:17 -0400860 public String getConferenceDetails(final String callID) throws RemoteException {
861 class ConfDetails extends SipRunnableWithReturn {
862 @Override
863 protected StringMap doRun() throws SameThreadException {
Alexandre Lisionc8397da2014-04-16 15:03:22 -0400864 Log.i(TAG, "SipService.getConferenceDetails() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400865 return SFLPhoneservice.sflph_call_get_conference_details(callID);
alision806e18e2013-06-21 15:30:17 -0400866 }
867 }
alision806e18e2013-06-21 15:30:17 -0400868 ConfDetails runInstance = new ConfDetails();
869 getExecutor().execute(runInstance);
870 while (!runInstance.isDone()) {
871 // Log.w(TAG, "Waiting for getConferenceList");
872 }
873 StringMap swigvect = (StringMap) runInstance.getVal();
874
875 return swigvect.get("CONF_STATE");
alision7f18fc82013-05-01 09:37:33 -0400876 }
877
alision04a00182013-05-10 17:05:29 -0400878 @Override
879 public String getRecordPath() throws RemoteException {
880 class RecordPath extends SipRunnableWithReturn {
881
882 @Override
883 protected String doRun() throws SameThreadException {
884 Log.i(TAG, "SipService.getRecordPath() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400885 return SFLPhoneservice.sflph_config_get_record_path();
alision04a00182013-05-10 17:05:29 -0400886 }
887 }
888
889 RecordPath runInstance = new RecordPath();
890 getExecutor().execute(runInstance);
891 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400892 // Log.w(TAG, "Waiting for getRecordPath");
alision04a00182013-05-10 17:05:29 -0400893 }
alision04a00182013-05-10 17:05:29 -0400894
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400895 return (String) runInstance.getVal();
alision04a00182013-05-10 17:05:29 -0400896 }
897
898 @Override
Alexandre Lisiona764c682013-09-09 10:02:07 -0400899 public boolean toggleRecordingCall(final String id) throws RemoteException {
Adrien Béraud9360f242013-09-19 11:07:42 +1000900
Alexandre Lisiona764c682013-09-09 10:02:07 -0400901 class ToggleRecording extends SipRunnableWithReturn {
902
alision04a00182013-05-10 17:05:29 -0400903 @Override
Alexandre Lisiona764c682013-09-09 10:02:07 -0400904 protected Boolean doRun() throws SameThreadException {
905 Log.i(TAG, "SipService.toggleRecordingCall() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400906 boolean result = SFLPhoneservice.sflph_call_toggle_recording(id);
Alexandre Lision35577132013-12-06 15:21:15 -0500907
Alexandre Lision945e4612014-01-15 17:40:31 -0500908 if (getConferences().containsKey(id)) {
909 getConferences().get(id).setRecording(result);
Alexandre Lision3874e552013-11-04 17:20:12 -0500910 } else {
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400911 for (Conference c : getConferences().values()) {
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500912 if (c.getCallById(id) != null)
913 c.getCallById(id).setRecording(result);
Alexandre Lision3874e552013-11-04 17:20:12 -0500914 }
915 }
916 return result;
alision04a00182013-05-10 17:05:29 -0400917 }
Alexandre Lisiona764c682013-09-09 10:02:07 -0400918 }
919
920 ToggleRecording runInstance = new ToggleRecording();
921 getExecutor().execute(runInstance);
922 while (!runInstance.isDone()) {
923 }
924
925 return (Boolean) runInstance.getVal();
alision04a00182013-05-10 17:05:29 -0400926
927 }
Alexandre Lision67817192013-07-18 12:04:30 -0400928
alision50fa0722013-06-25 17:29:44 -0400929 @Override
930 public boolean startRecordedFilePlayback(final String filepath) throws RemoteException {
931 getExecutor().execute(new SipRunnable() {
932 @Override
933 protected void doRun() throws SameThreadException, RemoteException {
934 Log.i(TAG, "SipService.setRecordingCall() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400935 SFLPhoneservice.sflph_call_play_recorded_file(filepath);
alision50fa0722013-06-25 17:29:44 -0400936 }
937 });
938 return false;
939 }
940
941 @Override
942 public void stopRecordedFilePlayback(final String filepath) throws RemoteException {
943 getExecutor().execute(new SipRunnable() {
944 @Override
945 protected void doRun() throws SameThreadException, RemoteException {
946 Log.i(TAG, "SipService.stopRecordedFilePlayback() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400947 SFLPhoneservice.sflph_call_stop_recorded_file(filepath);
alision50fa0722013-06-25 17:29:44 -0400948 }
949 });
950 }
alision04a00182013-05-10 17:05:29 -0400951
952 @Override
953 public void setRecordPath(final String path) throws RemoteException {
954 getExecutor().execute(new SipRunnable() {
955 @Override
956 protected void doRun() throws SameThreadException, RemoteException {
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400957 Log.i(TAG, "SipService.setRecordPath() " + path + " thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400958 SFLPhoneservice.sflph_config_set_record_path(path);
alision04a00182013-05-10 17:05:29 -0400959 }
960 });
961 }
962
963 @Override
Alexandre Lisiond5686032013-10-29 11:09:21 -0400964 public void sendTextMessage(final String callID, final SipMessage message) throws RemoteException {
alision04a00182013-05-10 17:05:29 -0400965 getExecutor().execute(new SipRunnable() {
966 @Override
967 protected void doRun() throws SameThreadException, RemoteException {
968 Log.i(TAG, "SipService.sendTextMessage() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400969 SFLPhoneservice.sflph_call_send_text_message(callID, message.comment);
Alexandre Lision945e4612014-01-15 17:40:31 -0500970 if (getConferences().get(callID) != null)
971 getConferences().get(callID).addSipMessage(message);
alision04a00182013-05-10 17:05:29 -0400972 }
973 });
974
975 }
976
alisiond295ec22013-05-17 10:12:13 -0400977 @Override
Alexandre Lision4cf78702013-10-16 13:43:23 -0400978 public List getAudioCodecList(final String accountID) throws RemoteException {
Alexandre Lisionafd40e42013-10-15 13:48:37 -0400979 class AudioCodecList extends SipRunnableWithReturn {
980
981 @Override
Alexandre Lision933ef0a2013-10-15 17:28:40 -0400982 protected ArrayList<Codec> doRun() throws SameThreadException {
Alexandre Lisionafd40e42013-10-15 13:48:37 -0400983 Log.i(TAG, "SipService.getAudioCodecList() thread running...");
Alexandre Lision4b4233a2013-10-16 17:24:17 -0400984 ArrayList<Codec> results = new ArrayList<Codec>();
Alexandre Lision4cf78702013-10-16 13:43:23 -0400985
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400986 IntVect active_payloads = SFLPhoneservice.sflph_config_get_active_audio_codec_list(accountID);
Alexandre Lision4b4233a2013-10-16 17:24:17 -0400987 for (int i = 0; i < active_payloads.size(); ++i) {
988
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400989 results.add(new Codec(active_payloads.get(i), SFLPhoneservice.sflph_config_get_audio_codec_details(active_payloads.get(i)), true));
Alexandre Lisione0045442013-10-25 09:16:19 -0400990
Alexandre Lision4cf78702013-10-16 13:43:23 -0400991 }
Alexandre Lisionfc91a462014-08-07 18:21:07 -0400992 IntVect payloads = SFLPhoneservice.sflph_config_get_audio_codec_list();
Alexandre Lision039a3cf2013-10-16 17:44:57 -0400993
994 for (int i = 0; i < payloads.size(); ++i) {
995 boolean isActive = false;
996 for (Codec co : results) {
997 if (co.getPayload().toString().contentEquals(String.valueOf(payloads.get(i))))
998 isActive = true;
999
1000 }
1001 if (isActive)
1002 continue;
1003 else
Alexandre Lisionfc91a462014-08-07 18:21:07 -04001004 results.add(new Codec(payloads.get(i), SFLPhoneservice.sflph_config_get_audio_codec_details(payloads.get(i)), false));
Alexandre Lision039a3cf2013-10-16 17:44:57 -04001005
1006 }
1007
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001008 return results;
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001009 }
1010 }
1011
1012 AudioCodecList runInstance = new AudioCodecList();
1013 getExecutor().execute(runInstance);
1014 while (!runInstance.isDone()) {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001015 }
Alexandre Lisionfc91a462014-08-07 18:21:07 -04001016 return (ArrayList<Codec>) runInstance.getVal();
alisiond295ec22013-05-17 10:12:13 -04001017 }
1018
alision9f7a6ec2013-05-24 16:26:26 -04001019 @Override
Alexandre Lision4cf78702013-10-16 13:43:23 -04001020 public Map getRingtoneList() throws RemoteException {
1021 class RingtoneList extends SipRunnableWithReturn {
1022
1023 @Override
1024 protected StringMap doRun() throws SameThreadException {
1025 Log.i(TAG, "SipService.getRingtoneList() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -04001026 return SFLPhoneservice.sflph_config_get_ringtone_list();
Alexandre Lision4cf78702013-10-16 13:43:23 -04001027 }
1028 }
1029
1030 RingtoneList runInstance = new RingtoneList();
1031 getExecutor().execute(runInstance);
1032 while (!runInstance.isDone()) {
1033 }
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001034 StringMap ringtones = (StringMap) runInstance.getVal();
1035
1036 for (int i = 0; i < ringtones.size(); ++i) {
1037 // Log.i(TAG,"ringtones "+i+" "+ ringtones.);
1038 }
1039
Alexandre Lision4cf78702013-10-16 13:43:23 -04001040 return null;
1041 }
1042
1043 @Override
Alexandre Lision1e61e302014-04-10 15:05:03 -04001044 public boolean checkForPrivateKey(final String pemPath) throws RemoteException {
1045 class hasPrivateKey extends SipRunnableWithReturn {
1046
1047 @Override
1048 protected Boolean doRun() throws SameThreadException {
1049 Log.i(TAG, "SipService.isCaptureMuted() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -04001050 return SFLPhoneservice.sflph_config_check_for_private_key(pemPath);
Alexandre Lision1e61e302014-04-10 15:05:03 -04001051 }
1052 }
1053
1054 hasPrivateKey runInstance = new hasPrivateKey();
1055 getExecutor().execute(runInstance);
1056 while (!runInstance.isDone()) {
1057 }
1058
1059 return (Boolean) runInstance.getVal();
1060 }
1061
1062 @Override
1063 public boolean checkCertificateValidity(final String pemPath) throws RemoteException {
1064 class isValid extends SipRunnableWithReturn {
1065
1066 @Override
1067 protected Boolean doRun() throws SameThreadException {
1068 Log.i(TAG, "SipService.isCaptureMuted() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -04001069 return SFLPhoneservice.sflph_config_check_certificate_validity(pemPath, pemPath);
Alexandre Lision1e61e302014-04-10 15:05:03 -04001070 }
1071 }
1072
1073 isValid runInstance = new isValid();
1074 getExecutor().execute(runInstance);
1075 while (!runInstance.isDone()) {
1076 }
1077
1078 return (Boolean) runInstance.getVal();
1079 }
1080
1081 @Override
1082 public boolean checkHostnameCertificate(final String certificatePath, final String host, final String port) throws RemoteException {
1083 class isValid extends SipRunnableWithReturn {
1084
1085 @Override
1086 protected Boolean doRun() throws SameThreadException {
1087 Log.i(TAG, "SipService.isCaptureMuted() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -04001088 return SFLPhoneservice.sflph_config_check_hostname_certificate(host, port);
Alexandre Lision1e61e302014-04-10 15:05:03 -04001089 }
1090 }
1091
1092 isValid runInstance = new isValid();
1093 getExecutor().execute(runInstance);
1094 while (!runInstance.isDone()) {
1095 }
1096
1097 return (Boolean) runInstance.getVal();
1098 }
1099
1100 @Override
Alexandre Lision4cf78702013-10-16 13:43:23 -04001101 public void setActiveCodecList(final List codecs, final String accountID) throws RemoteException {
1102 getExecutor().execute(new SipRunnable() {
1103 @Override
1104 protected void doRun() throws SameThreadException, RemoteException {
1105 Log.i(TAG, "SipService.setActiveAudioCodecList() thread running...");
1106 StringVect list = new StringVect();
Alexandre Lisionfc91a462014-08-07 18:21:07 -04001107 for (Object codec : codecs) {
1108 list.add((String) codec);
Alexandre Lision4cf78702013-10-16 13:43:23 -04001109 }
Alexandre Lisionfc91a462014-08-07 18:21:07 -04001110 SFLPhoneservice.sflph_config_set_active_audio_codec_list(list, accountID);
Alexandre Lision4cf78702013-10-16 13:43:23 -04001111 }
1112 });
1113 }
1114
alisioncc7bb422013-06-06 15:31:39 -04001115
alisiondf1dac92013-06-27 17:35:53 -04001116 @Override
1117 public Conference getCurrentCall() throws RemoteException {
Alexandre Lision945e4612014-01-15 17:40:31 -05001118 for (Conference conf : mConferences.values()) {
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -05001119 if (conf.isIncoming())
1120 return conf;
alisiondf1dac92013-06-27 17:35:53 -04001121 }
Alexandre Lision67817192013-07-18 12:04:30 -04001122
Alexandre Lision945e4612014-01-15 17:40:31 -05001123 for (Conference conf : mConferences.values()) {
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -05001124 if (conf.isOnGoing())
1125 return conf;
alisiondf1dac92013-06-27 17:35:53 -04001126 }
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -05001127
alisiondf1dac92013-06-27 17:35:53 -04001128 return null;
1129 }
1130
Alexandre Lision64dc8c02013-09-25 15:32:25 -04001131 @Override
1132 public void playDtmf(final String key) throws RemoteException {
1133 getExecutor().execute(new SipRunnable() {
1134 @Override
1135 protected void doRun() throws SameThreadException, RemoteException {
1136 Log.i(TAG, "SipService.playDtmf() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -04001137 SFLPhoneservice.sflph_call_play_dtmf(key);
Alexandre Lision64dc8c02013-09-25 15:32:25 -04001138 }
1139 });
1140 }
1141
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001142 @Override
1143 public List getConcurrentCalls() throws RemoteException {
Alexandre Lision945e4612014-01-15 17:40:31 -05001144 return new ArrayList(mConferences.values());
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -05001145 }
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001146
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -05001147 @Override
1148 public Conference getConference(String id) throws RemoteException {
Alexandre Lision945e4612014-01-15 17:40:31 -05001149 return mConferences.get(id);
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001150 }
1151
Alexandre Lision4fb22622013-10-21 16:26:33 -04001152 @Override
Alexandre Lision31e30902013-11-08 15:16:59 -05001153 public void setMuted(final boolean mute) throws RemoteException {
1154 getExecutor().execute(new SipRunnable() {
1155 @Override
1156 protected void doRun() throws SameThreadException, RemoteException {
1157 Log.i(TAG, "SipService.setMuted() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -04001158 SFLPhoneservice.sflph_config_mute_capture(mute);
Alexandre Lision31e30902013-11-08 15:16:59 -05001159 }
1160 });
1161 }
1162
1163 @Override
1164 public boolean isCaptureMuted() throws RemoteException {
1165 class IsMuted extends SipRunnableWithReturn {
1166
1167 @Override
1168 protected Boolean doRun() throws SameThreadException {
1169 Log.i(TAG, "SipService.isCaptureMuted() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -04001170 return SFLPhoneservice.sflph_config_is_capture_muted();
Alexandre Lision31e30902013-11-08 15:16:59 -05001171 }
1172 }
1173
1174 IsMuted runInstance = new IsMuted();
1175 getExecutor().execute(runInstance);
1176 while (!runInstance.isDone()) {
1177 }
1178
1179 return (Boolean) runInstance.getVal();
1180 }
1181
Alexandre Lision3b7148e2013-11-13 17:23:06 -05001182 @Override
Alexandre Lision48b49eb2014-02-11 13:37:33 -05001183 public void confirmSAS(final String callID) throws RemoteException {
1184 getExecutor().execute(new SipRunnable() {
1185 @Override
1186 protected void doRun() throws SameThreadException, RemoteException {
1187 Log.i(TAG, "SipService.confirmSAS() thread running...");
Alexandre Lision1b932d82014-02-21 10:03:19 -05001188 SecureSipCall call = (SecureSipCall) getCallById(callID);
Alexandre Lision651b5262014-02-21 17:14:14 -05001189 call.setSASConfirmed(true);
Alexandre Lisionfc91a462014-08-07 18:21:07 -04001190 SFLPhoneservice.sflph_call_set_sas_verified(callID);
Alexandre Lision48b49eb2014-02-11 13:37:33 -05001191 }
1192 });
1193 }
1194
Alexandre Lision509a7552014-03-04 13:37:50 -05001195
1196 @Override
1197 public List getTlsSupportedMethods(){
1198 class TlsMethods extends SipRunnableWithReturn {
1199
1200 @Override
1201 protected List doRun() throws SameThreadException {
1202 Log.i(TAG, "SipService.getCredentials() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -04001203 StringVect map = SFLPhoneservice.sflph_config_get_supported_tls_method();
1204 return SwigNativeConverter.convertSwigToNative(map);
Alexandre Lision509a7552014-03-04 13:37:50 -05001205 }
1206 }
1207
1208 TlsMethods runInstance = new TlsMethods();
1209 getExecutor().execute(runInstance);
1210 while (!runInstance.isDone()) {
1211 }
1212 return (List) runInstance.getVal();
1213 }
1214
Alexandre Lision48b49eb2014-02-11 13:37:33 -05001215 @Override
Alexandre Lision3b7148e2013-11-13 17:23:06 -05001216 public List getCredentials(final String accountID) throws RemoteException {
1217 class Credentials extends SipRunnableWithReturn {
1218
1219 @Override
1220 protected List doRun() throws SameThreadException {
1221 Log.i(TAG, "SipService.getCredentials() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -04001222 VectMap map = SFLPhoneservice.sflph_config_get_credentials(accountID);
1223 return SwigNativeConverter.convertCredentialsToNative(map);
Alexandre Lision3b7148e2013-11-13 17:23:06 -05001224 }
1225 }
1226
1227 Credentials runInstance = new Credentials();
1228 getExecutor().execute(runInstance);
1229 while (!runInstance.isDone()) {
1230 }
1231 return (List) runInstance.getVal();
1232 }
1233
1234 @Override
1235 public void setCredentials(final String accountID, final List creds) throws RemoteException {
1236 getExecutor().execute(new SipRunnable() {
1237 @Override
1238 protected void doRun() throws SameThreadException, RemoteException {
1239 Log.i(TAG, "SipService.setCredentials() thread running...");
Alexandre Lision3cefec22013-11-14 17:26:35 -05001240 ArrayList<HashMap<String, String>> list = (ArrayList<HashMap<String, String>>) creds;
Alexandre Lisionfc91a462014-08-07 18:21:07 -04001241 SFLPhoneservice.sflph_config_set_credentials(accountID, SwigNativeConverter.convertFromNativeToSwig(creds));
Alexandre Lision3b7148e2013-11-13 17:23:06 -05001242 }
1243 });
1244 }
1245
Alexandre Lision3e2a1d02013-11-19 17:23:00 -05001246 @Override
1247 public void registerAllAccounts() throws RemoteException {
1248 getExecutor().execute(new SipRunnable() {
1249 @Override
1250 protected void doRun() throws SameThreadException, RemoteException {
1251 Log.i(TAG, "SipService.registerAllAccounts() thread running...");
Alexandre Lisionfc91a462014-08-07 18:21:07 -04001252 SFLPhoneservice.sflph_config_register_all_accounts();
Alexandre Lision3e2a1d02013-11-19 17:23:00 -05001253 }
1254 });
1255 }
1256
Alexandre Lision5f733bc2013-12-04 13:10:30 -05001257 @Override
Alexandre Lision35577132013-12-06 15:21:15 -05001258 public void toggleSpeakerPhone(boolean toggle) throws RemoteException {
1259 if (toggle)
Alexandre Lision945e4612014-01-15 17:40:31 -05001260 mMediaManager.RouteToSpeaker();
Alexandre Lision35577132013-12-06 15:21:15 -05001261 else
Alexandre Lision945e4612014-01-15 17:40:31 -05001262 mMediaManager.RouteToInternalSpeaker();
Alexandre Lision5f733bc2013-12-04 13:10:30 -05001263 }
1264
Emeric Vigier6119d782012-09-21 18:04:14 -04001265 };
Alexandre Lision3c37dca2014-02-21 14:13:26 -05001266
1267 private void removeCall(String callID) {
1268 Conference conf = findConference(callID);
1269 if(conf == null)
1270 return;
1271 if(conf.getParticipants().size() == 1)
1272 getConferences().remove(conf.getId());
1273 else
1274 conf.removeParticipant(conf.getCallById(callID));
1275 }
1276
1277 protected Conference findConference(String callID) {
1278 Conference result = null;
1279 if (getConferences().get(callID) != null) {
1280 result = getConferences().get(callID);
1281 } else {
Alexandre Lision96a1ef02014-09-03 15:28:08 -04001282 for (Entry<String, Conference> stringConferenceEntry : getConferences().entrySet()) {
1283 Conference tmp = stringConferenceEntry.getValue();
Alexandre Lision3c37dca2014-02-21 14:13:26 -05001284 for (SipCall c : tmp.getParticipants()) {
1285 if (c.getCallId().contentEquals(callID)) {
1286 result = tmp;
1287 }
1288 }
1289 }
1290 }
1291 return result;
1292 }
Alexandre Lision35577132013-12-06 15:21:15 -05001293}