blob: ad45073c6d37b060a178e70cad931c67bbf0bb1e [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
alision17052d42013-04-22 10:39:38 -040027import java.util.ArrayList;
28import java.util.HashMap;
alisioncc7bb422013-06-06 15:31:39 -040029import java.util.Iterator;
alision7f18fc82013-05-01 09:37:33 -040030import java.util.List;
alision17052d42013-04-22 10:39:38 -040031import java.util.Map;
alision806e18e2013-06-21 15:30:17 -040032import java.util.Map.Entry;
Emeric Vigier6119d782012-09-21 18:04:14 -040033
Alexandre Lision651b5262014-02-21 17:14:14 -050034import org.sflphone.account.AccountDetailSrtp;
Alexandre Lision945e4612014-01-15 17:40:31 -050035import org.sflphone.history.HistoryManager;
Alexandre Lisiona7ab2e32014-02-14 15:33:33 -050036import org.sflphone.model.*;
Alexandre Lision6d867b92013-10-25 15:36:28 -040037import org.sflphone.utils.MediaManager;
Alexandre Lisione0045442013-10-25 09:16:19 -040038import org.sflphone.utils.SipNotifications;
Alexandre Lision2aae48d2013-12-04 13:50:38 -050039import org.sflphone.utils.SwigNativeConverter;
Alexandre Lision064e1e02013-10-01 16:18:42 -040040
Emeric Vigiereaf2c492012-09-19 14:38:20 -040041import android.app.Service;
42import android.content.Intent;
alision7f18fc82013-05-01 09:37:33 -040043import android.os.Bundle;
Emeric Vigier6119d782012-09-21 18:04:14 -040044import android.os.Handler;
45import android.os.HandlerThread;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040046import android.os.IBinder;
Emeric Vigier6119d782012-09-21 18:04:14 -040047import android.os.Looper;
48import android.os.Message;
alision5f899632013-04-22 17:26:56 -040049import android.os.RemoteException;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040050import android.util.Log;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040051
Emeric Vigiereaf2c492012-09-19 14:38:20 -040052public class SipService extends Service {
53
54 static final String TAG = "SipService";
Emeric Vigier6119d782012-09-21 18:04:14 -040055 private SipServiceExecutor mExecutor;
56 private static HandlerThread executorThread;
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -050057
alision3ea8f3c2013-07-16 17:35:35 -040058 private CallManager callManagerJNI;
Alexandre Lision67817192013-07-18 12:04:30 -040059 private ManagerImpl managerImpl;
Emeric Vigier0007dee2012-09-24 11:35:58 -040060 private CallManagerCallBack callManagerCallBack;
Alexandre Lisionb2669692014-01-28 14:06:08 -050061
alision3ea8f3c2013-07-16 17:35:35 -040062 private ConfigurationManager configurationManagerJNI;
Alexandre Savardfccd1dc2012-10-17 17:31:38 -040063 private ConfigurationManagerCallback configurationManagerCallback;
Emeric Vigier6119d782012-09-21 18:04:14 -040064 private boolean isPjSipStackStarted = false;
alisioncc7bb422013-06-06 15:31:39 -040065
Alexandre Lision945e4612014-01-15 17:40:31 -050066 protected SipNotifications mNotificationManager;
67 protected HistoryManager mHistoryManager;
68 protected MediaManager mMediaManager;
Alexandre Lisione0045442013-10-25 09:16:19 -040069
Alexandre Lision945e4612014-01-15 17:40:31 -050070 private HashMap<String, Conference> mConferences = new HashMap<String, Conference>();
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 Lisionb2669692014-01-28 14:06:08 -050076 public CallManager getCallManagerJNI() {
77 return callManagerJNI;
78 }
79
80 public ConfigurationManager getConfigurationManagerJNI() {
81 return configurationManagerJNI;
82 }
83
Alexandre Lision183bf452014-01-17 11:21:59 -050084 public void addCallToConference(String confId, String callId) {
85 if(mConferences.get(callId) != null){
86 // We add a simple call to a conference
Alexandre Lision96db8032014-01-17 16:43:51 -050087 Log.i(TAG, "// We add a simple call to a conference");
Alexandre Lision183bf452014-01-17 11:21:59 -050088 mConferences.get(confId).addParticipant(mConferences.get(callId).getParticipants().get(0));
89 mConferences.remove(callId);
90 } else {
Alexandre Lision96db8032014-01-17 16:43:51 -050091 Log.i(TAG, "addCallToConference");
Alexandre Lision183bf452014-01-17 11:21:59 -050092 Iterator<Map.Entry<String, Conference>> it = mConferences.entrySet().iterator();
93 while (it.hasNext()) {
94 Conference tmp = it.next().getValue();
95 for (SipCall c : tmp.getParticipants()) {
96 if (c.getCallId().contentEquals(callId)) {
97 mConferences.get(confId).addParticipant(c);
Alexandre Lision96db8032014-01-17 16:43:51 -050098 mConferences.get(tmp.getId()).removeParticipant(c);
Alexandre Lision183bf452014-01-17 11:21:59 -050099 }
100 }
101 }
102 }
103
104 }
105
Alexandre Lision96db8032014-01-17 16:43:51 -0500106 public void detachCallFromConference(String confId, SipCall call) {
107 Log.i(TAG, "detachCallFromConference");
Alexandre Lision183bf452014-01-17 11:21:59 -0500108 Conference separate = new Conference(call);
109 mConferences.put(separate.getId(), separate);
Alexandre Lision96db8032014-01-17 16:43:51 -0500110 mConferences.get(confId).removeParticipant(call);
Alexandre Lision183bf452014-01-17 11:21:59 -0500111 }
112
113
alision43a9b362013-05-01 16:30:15 -0400114 @Override
115 public boolean onUnbind(Intent i) {
116 super.onUnbind(i);
117 Log.i(TAG, "onUnbind(intent)");
Alexandre Lision0f550ee2013-10-25 15:34:38 -0400118 return true;
119 }
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400120
Alexandre Lision0f550ee2013-10-25 15:34:38 -0400121 @Override
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400122 public void onRebind(Intent i) {
Alexandre Lision0f550ee2013-10-25 15:34:38 -0400123 super.onRebind(i);
alision43a9b362013-05-01 16:30:15 -0400124 }
125
126 /* called once by startService() */
127 @Override
128 public void onCreate() {
129 Log.i(TAG, "onCreated");
130 super.onCreate();
131
alisioncc7bb422013-06-06 15:31:39 -0400132 getExecutor().execute(new StartRunnable());
Alexandre Lisione0045442013-10-25 09:16:19 -0400133
Alexandre Lision945e4612014-01-15 17:40:31 -0500134 mNotificationManager = new SipNotifications(this);
135 mMediaManager = new MediaManager(this);
136 mHistoryManager = new HistoryManager(this);
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400137
Alexandre Lision945e4612014-01-15 17:40:31 -0500138 mNotificationManager.onServiceCreate();
139 mMediaManager.startService();
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400140
alisioncc7bb422013-06-06 15:31:39 -0400141 }
alision43a9b362013-05-01 16:30:15 -0400142
143 /* called for each startService() */
144 @Override
145 public int onStartCommand(Intent intent, int flags, int startId) {
146 Log.i(TAG, "onStarted");
147 super.onStartCommand(intent, flags, startId);
Alexandre Lision0f550ee2013-10-25 15:34:38 -0400148 return START_STICKY; /* started and stopped explicitly */
alision43a9b362013-05-01 16:30:15 -0400149 }
150
151 @Override
152 public void onDestroy() {
Alexandre Lision52214992013-10-28 17:41:23 -0400153 Log.i(TAG, "onDestroy");
alision43a9b362013-05-01 16:30:15 -0400154 /* called once by stopService() */
Alexandre Lision945e4612014-01-15 17:40:31 -0500155 mNotificationManager.onServiceDestroy();
Alexandre Lision183bf452014-01-17 11:21:59 -0500156 mMediaManager.stopService();
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400157 getExecutor().execute(new FinalizeRunnable());
alision43a9b362013-05-01 16:30:15 -0400158 super.onDestroy();
159
alision43a9b362013-05-01 16:30:15 -0400160 }
161
162 @Override
163 public IBinder onBind(Intent arg0) {
164 Log.i(TAG, "onBound");
165 return mBinder;
166 }
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400167
alision43a9b362013-05-01 16:30:15 -0400168 private static Looper createLooper() {
169 if (executorThread == null) {
170 Log.d(TAG, "Creating new handler thread");
171 // ADT gives a fake warning due to bad parse rule.
172 executorThread = new HandlerThread("SipService.Executor");
173 executorThread.start();
174 }
175 return executorThread.getLooper();
176 }
177
178 public SipServiceExecutor getExecutor() {
179 // create mExecutor lazily
180 if (mExecutor == null) {
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500181 mExecutor = new SipServiceExecutor();
alision43a9b362013-05-01 16:30:15 -0400182 }
183 return mExecutor;
184 }
185
Alexandre Lision5f144b82014-02-11 09:59:36 -0500186 public SipCall getCallById(String callID) {
187 if (getConferences().get(callID) != null) {
188 return getConferences().get(callID).getCallById(callID);
189 } else {
190 // Check if call is in a conference
191 Iterator<Map.Entry<String, Conference>> it = getConferences().entrySet().iterator();
192 while (it.hasNext()) {
193 Conference tmp = it.next().getValue();
194 SipCall c = tmp.getCallById(callID);
195 if(c != null)
196 return c;
197 }
198 }
199 return null;
200 }
201
alision43a9b362013-05-01 16:30:15 -0400202 // Executes immediate tasks in a single executorThread.
203 public static class SipServiceExecutor extends Handler {
alision43a9b362013-05-01 16:30:15 -0400204
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500205 SipServiceExecutor() {
alision43a9b362013-05-01 16:30:15 -0400206 super(createLooper());
alision43a9b362013-05-01 16:30:15 -0400207 }
208
209 public void execute(Runnable task) {
210 // TODO: add wakelock
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500211 Message.obtain(SipServiceExecutor.this, 0/* don't care */, task).sendToTarget();
Alexandre Lisioncdec5952013-07-17 14:18:22 -0400212 Log.w(TAG, "SenT!");
alision43a9b362013-05-01 16:30:15 -0400213 }
214
215 @Override
216 public void handleMessage(Message msg) {
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500217 Log.w(TAG, "handleMessage");
alision43a9b362013-05-01 16:30:15 -0400218 if (msg.obj instanceof Runnable) {
219 executeInternal((Runnable) msg.obj);
220 } else {
221 Log.w(TAG, "can't handle msg: " + msg);
222 }
223 }
224
225 private void executeInternal(Runnable task) {
226 try {
227 task.run();
228 } catch (Throwable t) {
229 Log.e(TAG, "run task: " + task, t);
230 }
231 }
232 }
Alexandre Lision63870a72013-10-28 16:33:47 -0400233
234 private void stopDaemon() {
235 if (managerImpl != null) {
236 managerImpl.finish();
237 isPjSipStackStarted = false;
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400238 }
239 }
alision43a9b362013-05-01 16:30:15 -0400240
241 private void startPjSipStack() throws SameThreadException {
242 if (isPjSipStackStarted)
243 return;
244
245 try {
246 System.loadLibrary("gnustl_shared");
alision43a9b362013-05-01 16:30:15 -0400247 System.loadLibrary("crypto");
248 System.loadLibrary("ssl");
alision43a9b362013-05-01 16:30:15 -0400249 System.loadLibrary("sflphone");
250 isPjSipStackStarted = true;
Adrien Béraud9360f242013-09-19 11:07:42 +1000251
alision43a9b362013-05-01 16:30:15 -0400252 } catch (UnsatisfiedLinkError e) {
253 Log.e(TAG, "Problem with the current Pj stack...", e);
254 isPjSipStackStarted = false;
255 return;
256 } catch (Exception e) {
257 Log.e(TAG, "Problem with the current Pj stack...", e);
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400258 isPjSipStackStarted = false;
alision43a9b362013-05-01 16:30:15 -0400259 }
260
Alexandre Lision67817192013-07-18 12:04:30 -0400261 Log.i(TAG, "PjSIPStack started");
262 managerImpl = SFLPhoneservice.instance();
263
264 /* set static AppPath before calling manager.init */
Alexandre Lision63870a72013-10-28 16:33:47 -0400265 // managerImpl.setPath(getApplication().getFilesDir().getAbsolutePath());
alision43a9b362013-05-01 16:30:15 -0400266
alision3ea8f3c2013-07-16 17:35:35 -0400267 callManagerJNI = new CallManager();
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500268 callManagerCallBack = new CallManagerCallBack(this);
alision43a9b362013-05-01 16:30:15 -0400269 SFLPhoneservice.setCallbackObject(callManagerCallBack);
270
alision3ea8f3c2013-07-16 17:35:35 -0400271 configurationManagerJNI = new ConfigurationManager();
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500272 configurationManagerCallback = new ConfigurationManagerCallback(this);
alision43a9b362013-05-01 16:30:15 -0400273 SFLPhoneservice.setConfigurationCallbackObject(configurationManagerCallback);
Alexandre Lision67817192013-07-18 12:04:30 -0400274 managerImpl.init("");
Adrien Béraud9360f242013-09-19 11:07:42 +1000275
Alexandre Lision67817192013-07-18 12:04:30 -0400276 Log.i(TAG, "->startPjSipStack");
alision43a9b362013-05-01 16:30:15 -0400277 }
278
279 // Enforce same thread contract to ensure we do not call from somewhere else
280 public class SameThreadException extends Exception {
281 private static final long serialVersionUID = -905639124232613768L;
282
283 public SameThreadException() {
284 super("Should be launched from a single worker thread");
285 }
286 }
287
288 public abstract static class SipRunnable implements Runnable {
289 protected abstract void doRun() throws SameThreadException, RemoteException;
290
Adrien Béraud9360f242013-09-19 11:07:42 +1000291 @Override
alision43a9b362013-05-01 16:30:15 -0400292 public void run() {
293 try {
294 doRun();
295 } catch (SameThreadException e) {
296 Log.e(TAG, "Not done from same thread");
297 } catch (RemoteException e) {
298 Log.e(TAG, e.toString());
299 }
300 }
301 }
302
Alexandre Lisionfab23f82013-11-01 11:22:30 -0400303 public abstract class SipRunnableWithReturn implements Runnable {
alision43a9b362013-05-01 16:30:15 -0400304 Object obj = null;
305 boolean done = false;
306
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500307 protected abstract Object doRun() throws SameThreadException, RemoteException;
alision43a9b362013-05-01 16:30:15 -0400308
309 public Object getVal() {
310 return obj;
311 }
312
313 public boolean isDone() {
314 return done;
315 }
316
Adrien Béraud9360f242013-09-19 11:07:42 +1000317 @Override
alision43a9b362013-05-01 16:30:15 -0400318 public void run() {
319 try {
Alexandre Lision35577132013-12-06 15:21:15 -0500320 if (isPjSipStackStarted)
Alexandre Lisionfab23f82013-11-01 11:22:30 -0400321 obj = doRun();
alision43a9b362013-05-01 16:30:15 -0400322 done = true;
323 } catch (SameThreadException e) {
324 Log.e(TAG, "Not done from same thread");
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500325 } catch (RemoteException e) {
326 Log.e(TAG, e.toString());
alision43a9b362013-05-01 16:30:15 -0400327 }
328 }
329 }
330
331 class StartRunnable extends SipRunnable {
332 @Override
333 protected void doRun() throws SameThreadException {
334 startPjSipStack();
335 }
336 }
Alexandre Lision63870a72013-10-28 16:33:47 -0400337
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400338 class FinalizeRunnable extends SipRunnable {
339 @Override
340 protected void doRun() throws SameThreadException {
341 stopDaemon();
342 }
343 }
alision43a9b362013-05-01 16:30:15 -0400344
alision43a9b362013-05-01 16:30:15 -0400345 /* ************************************
346 *
347 * Implement public interface for the service
348 *
Alexandre Lision67817192013-07-18 12:04:30 -0400349 * *********************************
350 */
351
Emeric Vigier6119d782012-09-21 18:04:14 -0400352 private final ISipService.Stub mBinder = new ISipService.Stub() {
353
354 @Override
alisionfde875f2013-05-28 17:01:54 -0400355 public void placeCall(final SipCall call) {
Alexandre Lisiona7ab2e32014-02-14 15:33:33 -0500356
Emeric Vigier6119d782012-09-21 18:04:14 -0400357 getExecutor().execute(new SipRunnable() {
358 @Override
359 protected void doRun() throws SameThreadException {
360 Log.i(TAG, "SipService.placeCall() thread running...");
Alexandre Lision651b5262014-02-21 17:14:14 -0500361 Conference toAdd;
362 if(call.getAccount().useSecureLayer()){
363 Bundle secureArgs = new Bundle();
364 secureArgs.putBoolean(SecureSipCall.DISPLAY_SAS, call.getAccount().getSrtpDetails().getDetailBoolean(AccountDetailSrtp.CONFIG_ZRTP_DISPLAY_SAS));
365 secureArgs.putBoolean(SecureSipCall.DISPLAY_SAS_ONCE, call.getAccount().getSrtpDetails().getDetailBoolean(AccountDetailSrtp.CONFIG_ZRTP_DISPLAY_SAS_ONCE));
366 secureArgs.putBoolean(SecureSipCall.DISPLAY_WARNING_ZRTP_NOT_SUPPORTED, call.getAccount().getSrtpDetails().getDetailBoolean(AccountDetailSrtp.CONFIG_ZRTP_NOT_SUPP_WARNING));
367 SecureSipCall secureCall = new SecureSipCall(call, secureArgs);
368 toAdd = new Conference(secureCall);
369 } else {
370 toAdd = new Conference(call);
371 }
Alexandre Lision945e4612014-01-15 17:40:31 -0500372 mConferences.put(toAdd.getId(), toAdd);
373 mMediaManager.obtainAudioFocus(false);
Alexandre Lisiona7ab2e32014-02-14 15:33:33 -0500374 callManagerJNI.placeCall(call.getAccount().getAccountID(), call.getCallId(), call.getmContact().getPhones().get(0).getNumber());
Emeric Vigier6119d782012-09-21 18:04:14 -0400375 }
376 });
377 }
378
379 @Override
380 public void refuse(final String callID) {
Alexandre Lisionf02190d2013-12-12 17:26:12 -0500381
Emeric Vigier6119d782012-09-21 18:04:14 -0400382 getExecutor().execute(new SipRunnable() {
383 @Override
384 protected void doRun() throws SameThreadException {
385 Log.i(TAG, "SipService.refuse() thread running...");
386 callManagerJNI.refuse(callID);
387 }
388 });
389 }
390
391 @Override
392 public void accept(final String callID) {
Alexandre Lision945e4612014-01-15 17:40:31 -0500393 mMediaManager.stopRing();
Emeric Vigier6119d782012-09-21 18:04:14 -0400394 getExecutor().execute(new SipRunnable() {
395 @Override
396 protected void doRun() throws SameThreadException {
Tristan Matthews40cf25e2013-07-24 13:45:15 -0400397 Log.i(TAG, "SipService.accept() thread running...");
Emeric Vigier6119d782012-09-21 18:04:14 -0400398 callManagerJNI.accept(callID);
Alexandre Lision945e4612014-01-15 17:40:31 -0500399 mMediaManager.RouteToInternalSpeaker();
Emeric Vigier6119d782012-09-21 18:04:14 -0400400 }
401 });
402 }
403
404 @Override
405 public void hangUp(final String callID) {
Alexandre Lision945e4612014-01-15 17:40:31 -0500406 mMediaManager.stopRing();
Emeric Vigier6119d782012-09-21 18:04:14 -0400407 getExecutor().execute(new SipRunnable() {
408 @Override
409 protected void doRun() throws SameThreadException {
410 Log.i(TAG, "SipService.hangUp() thread running...");
411 callManagerJNI.hangUp(callID);
Alexandre Lision3c37dca2014-02-21 14:13:26 -0500412 removeCall(callID);
413 Log.i(TAG, "mConferences.size():"+mConferences.size());
414 if(mConferences.size() == 0) {
415 Log.i(TAG, "No more calls!");
Alexandre Lision183bf452014-01-17 11:21:59 -0500416 mMediaManager.abandonAudioFocus();
Alexandre Lision3c37dca2014-02-21 14:13:26 -0500417 }
Emeric Vigier6119d782012-09-21 18:04:14 -0400418 }
419 });
420 }
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400421
422 @Override
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400423 public void hold(final String callID) {
424 getExecutor().execute(new SipRunnable() {
425 @Override
426 protected void doRun() throws SameThreadException {
427 Log.i(TAG, "SipService.hold() thread running...");
428 callManagerJNI.hold(callID);
429 }
430 });
431 }
432
433 @Override
434 public void unhold(final String callID) {
435 getExecutor().execute(new SipRunnable() {
436 @Override
437 protected void doRun() throws SameThreadException {
438 Log.i(TAG, "SipService.unhold() thread running...");
439 callManagerJNI.unhold(callID);
440 }
441 });
442 }
Adrien Béraud9360f242013-09-19 11:07:42 +1000443
Alexandre Lision6711ab22013-09-16 15:15:38 -0400444 @Override
445 public HashMap<String, String> getCallDetails(String callID) throws RemoteException {
446 class CallDetails extends SipRunnableWithReturn {
447 private String id;
448
449 CallDetails(String callID) {
450 id = callID;
451 }
452
453 @Override
454 protected StringMap doRun() throws SameThreadException {
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400455 Log.i(TAG, "SipService.getCallDetails() thread running...");
Alexandre Lision6711ab22013-09-16 15:15:38 -0400456 return callManagerJNI.getCallDetails(id);
457 }
458 }
459
460 CallDetails runInstance = new CallDetails(callID);
461 getExecutor().execute(runInstance);
462
463 while (!runInstance.isDone()) {
464 }
465 StringMap swigmap = (StringMap) runInstance.getVal();
466
Alexandre Lision2aae48d2013-12-04 13:50:38 -0500467 HashMap<String, String> nativemap = SwigNativeConverter.convertCallDetailsToNative(swigmap);
Alexandre Lision6711ab22013-09-16 15:15:38 -0400468
469 return nativemap;
Adrien Béraud9360f242013-09-19 11:07:42 +1000470
Alexandre Lision6711ab22013-09-16 15:15:38 -0400471 }
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400472
473 @Override
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400474 public void setAudioPlugin(final String audioPlugin) {
475 getExecutor().execute(new SipRunnable() {
alision371b77e2013-04-23 14:51:26 -0400476 @Override
477 protected void doRun() throws SameThreadException {
478 Log.i(TAG, "SipService.setAudioPlugin() thread running...");
479 configurationManagerJNI.setAudioPlugin(audioPlugin);
480 }
Alexandre Savard31d27c62012-10-04 16:05:08 -0400481 });
482 }
483
484 @Override
485 public String getCurrentAudioOutputPlugin() {
486 class CurrentAudioPlugin extends SipRunnableWithReturn {
487 @Override
488 protected String doRun() throws SameThreadException {
489 Log.i(TAG, "SipService.getCurrentAudioOutputPlugin() thread running...");
490 return configurationManagerJNI.getCurrentAudioOutputPlugin();
491 }
alision371b77e2013-04-23 14:51:26 -0400492 }
493 ;
Alexandre Savard31d27c62012-10-04 16:05:08 -0400494
495 CurrentAudioPlugin runInstance = new CurrentAudioPlugin();
496 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400497 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400498 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400499 }
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400500 return (String) runInstance.getVal();
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400501 }
Alexandre Savard713a34d2012-09-26 15:50:41 -0400502
503 @Override
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400504 public ArrayList<String> getAccountList() {
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400505 class AccountList extends SipRunnableWithReturn {
506 @Override
507 protected StringVect doRun() throws SameThreadException {
508 Log.i(TAG, "SipService.getAccountList() thread running...");
509 return configurationManagerJNI.getAccountList();
510 }
alision371b77e2013-04-23 14:51:26 -0400511 }
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400512 AccountList runInstance = new AccountList();
Alexandre Lisioncdec5952013-07-17 14:18:22 -0400513 Log.i(TAG, "SipService.getAccountList() thread running...");
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400514 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400515 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400516 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400517 }
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400518 StringVect swigvect = (StringVect) runInstance.getVal();
519
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400520 ArrayList<String> nativelist = new ArrayList<String>();
Alexandre Savard52a72522012-09-27 16:40:13 -0400521
alision371b77e2013-04-23 14:51:26 -0400522 for (int i = 0; i < swigvect.size(); i++)
523 nativelist.add(swigvect.get(i));
Alexandre Savard52a72522012-09-27 16:40:13 -0400524
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400525 return nativelist;
alision371b77e2013-04-23 14:51:26 -0400526 }
Alexandre Lision4b4233a2013-10-16 17:24:17 -0400527
Alexandre Lision4cf78702013-10-16 13:43:23 -0400528 @Override
Alexandre Lision4b4233a2013-10-16 17:24:17 -0400529 public void setAccountOrder(final String order) {
Alexandre Lision4cf78702013-10-16 13:43:23 -0400530 getExecutor().execute(new SipRunnable() {
531 @Override
532 protected void doRun() throws SameThreadException {
533 Log.i(TAG, "SipService.setAccountsOrder() thread running...");
534 configurationManagerJNI.setAccountsOrder(order);
535 }
536 });
537 }
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400538
539 @Override
alision371b77e2013-04-23 14:51:26 -0400540 public HashMap<String, String> getAccountDetails(final String accountID) {
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400541 class AccountDetails extends SipRunnableWithReturn {
542 private String id;
alision371b77e2013-04-23 14:51:26 -0400543
544 AccountDetails(String accountId) {
545 id = accountId;
546 }
547
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400548 @Override
549 protected StringMap doRun() throws SameThreadException {
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400550 Log.i(TAG, "SipService.getAccountDetails() thread running...");
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400551 return configurationManagerJNI.getAccountDetails(id);
552 }
alision371b77e2013-04-23 14:51:26 -0400553 }
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400554
555 AccountDetails runInstance = new AccountDetails(accountID);
556 getExecutor().execute(runInstance);
alisionfde875f2013-05-28 17:01:54 -0400557
alision371b77e2013-04-23 14:51:26 -0400558 while (!runInstance.isDone()) {
559 }
560 StringMap swigmap = (StringMap) runInstance.getVal();
Alexandre Savard713a34d2012-09-26 15:50:41 -0400561
Alexandre Lision2aae48d2013-12-04 13:50:38 -0500562 HashMap<String, String> nativemap = SwigNativeConverter.convertAccountToNative(swigmap);
Alexandre Savard713a34d2012-09-26 15:50:41 -0400563
564 return nativemap;
565 }
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400566
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400567 @SuppressWarnings("unchecked")
568 // Hashmap runtime cast
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400569 @Override
alisioncc7bb422013-06-06 15:31:39 -0400570 public void setAccountDetails(final String accountId, final Map map) {
alision371b77e2013-04-23 14:51:26 -0400571 HashMap<String, String> nativemap = (HashMap<String, String>) map;
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400572
Alexandre Lision2aae48d2013-12-04 13:50:38 -0500573 final StringMap swigmap = SwigNativeConverter.convertFromNativeToSwig(nativemap);
Alexandre Savard718d49f2012-10-02 15:17:13 -0400574
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400575 getExecutor().execute(new SipRunnable() {
576 @Override
577 protected void doRun() throws SameThreadException {
alisioncc7bb422013-06-06 15:31:39 -0400578
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400579 configurationManagerJNI.setAccountDetails(accountId, swigmap);
alisioncc7bb422013-06-06 15:31:39 -0400580 Log.i(TAG, "SipService.setAccountDetails() thread running...");
581 }
582
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400583 });
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400584 }
585
Alexandre Lision451f2a82013-11-12 12:55:55 -0500586 @Override
587 public Map getAccountTemplate() throws RemoteException {
588 class AccountTemplate extends SipRunnableWithReturn {
589
590 @Override
591 protected StringMap doRun() throws SameThreadException {
592 Log.i(TAG, "SipService.getAccountTemplate() thread running...");
593 return configurationManagerJNI.getAccountTemplate();
594 }
595 }
596
597 AccountTemplate runInstance = new AccountTemplate();
598 getExecutor().execute(runInstance);
599
600 while (!runInstance.isDone()) {
601 }
602 StringMap swigmap = (StringMap) runInstance.getVal();
603
Alexandre Lision2aae48d2013-12-04 13:50:38 -0500604 HashMap<String, String> nativemap = SwigNativeConverter.convertAccountToNative(swigmap);
Alexandre Lision451f2a82013-11-12 12:55:55 -0500605
606 return nativemap;
607 }
alisioncc7bb422013-06-06 15:31:39 -0400608
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400609 @SuppressWarnings("unchecked")
610 // Hashmap runtime cast
Alexandre Savard46036572012-10-05 13:56:49 -0400611 @Override
612 public String addAccount(Map map) {
613 class AddAccount extends SipRunnableWithReturn {
614 StringMap map;
alision371b77e2013-04-23 14:51:26 -0400615
616 AddAccount(StringMap m) {
617 map = m;
618 }
619
Alexandre Savard46036572012-10-05 13:56:49 -0400620 @Override
621 protected String doRun() throws SameThreadException {
622 Log.i(TAG, "SipService.getAccountDetails() thread running...");
623 return configurationManagerJNI.addAccount(map);
624 }
alision371b77e2013-04-23 14:51:26 -0400625 }
Alexandre Savard46036572012-10-05 13:56:49 -0400626
Alexandre Lision2aae48d2013-12-04 13:50:38 -0500627 final StringMap swigmap = SwigNativeConverter.convertFromNativeToSwig((HashMap<String, String>) map);
Alexandre Savard46036572012-10-05 13:56:49 -0400628
629 AddAccount runInstance = new AddAccount(swigmap);
630 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400631 while (!runInstance.isDone()) {
632 }
Alexandre Savard46036572012-10-05 13:56:49 -0400633 String accountId = (String) runInstance.getVal();
634
635 return accountId;
636 }
637
638 @Override
639 public void removeAccount(final String accountId) {
640 getExecutor().execute(new SipRunnable() {
641 @Override
642 protected void doRun() throws SameThreadException {
643 Log.i(TAG, "SipService.setAccountDetails() thread running...");
644 configurationManagerJNI.removeAccount(accountId);
645 }
646 });
647 }
alision5f899632013-04-22 17:26:56 -0400648
alision43a9b362013-05-01 16:30:15 -0400649 /*************************
650 * Transfer related API
651 *************************/
652
alision7f18fc82013-05-01 09:37:33 -0400653 @Override
654 public void transfer(final String callID, final String to) throws RemoteException {
655 getExecutor().execute(new SipRunnable() {
656 @Override
657 protected void doRun() throws SameThreadException, RemoteException {
658 Log.i(TAG, "SipService.transfer() thread running...");
659 if (callManagerJNI.transfer(callID, to)) {
660 Bundle bundle = new Bundle();
661 bundle.putString("CallID", callID);
662 bundle.putString("State", "HUNGUP");
663 Intent intent = new Intent(CallManagerCallBack.CALL_STATE_CHANGED);
alision7f18fc82013-05-01 09:37:33 -0400664 intent.putExtra("com.savoirfairelinux.sflphone.service.newstate", bundle);
alision84813a12013-05-27 17:40:39 -0400665 sendBroadcast(intent);
alision7f18fc82013-05-01 09:37:33 -0400666 } else
667 Log.i(TAG, "NOT OK");
668 }
669 });
670
671 }
alision43a9b362013-05-01 16:30:15 -0400672
alision7f18fc82013-05-01 09:37:33 -0400673 @Override
674 public void attendedTransfer(final String transferID, final String targetID) throws RemoteException {
675 getExecutor().execute(new SipRunnable() {
676 @Override
677 protected void doRun() throws SameThreadException, RemoteException {
alision43a9b362013-05-01 16:30:15 -0400678 Log.i(TAG, "SipService.attendedTransfer() thread running...");
alision7f18fc82013-05-01 09:37:33 -0400679 if (callManagerJNI.attendedTransfer(transferID, targetID)) {
680 Log.i(TAG, "OK");
alision7f18fc82013-05-01 09:37:33 -0400681 } else
682 Log.i(TAG, "NOT OK");
683 }
684 });
alision43a9b362013-05-01 16:30:15 -0400685
686 }
687
688 /*************************
689 * Conference related API
690 *************************/
691
692 @Override
693 public void removeConference(final String confID) throws RemoteException {
694 getExecutor().execute(new SipRunnable() {
695 @Override
696 protected void doRun() throws SameThreadException, RemoteException {
697 Log.i(TAG, "SipService.createConference() thread running...");
698 callManagerJNI.removeConference(confID);
699 }
700 });
701
alision7f18fc82013-05-01 09:37:33 -0400702 }
703
704 @Override
alision43a9b362013-05-01 16:30:15 -0400705 public void joinParticipant(final String sel_callID, final String drag_callID) throws RemoteException {
706 getExecutor().execute(new SipRunnable() {
707 @Override
708 protected void doRun() throws SameThreadException, RemoteException {
709 Log.i(TAG, "SipService.joinParticipant() thread running...");
710 callManagerJNI.joinParticipant(sel_callID, drag_callID);
alision806e18e2013-06-21 15:30:17 -0400711 // Generate a CONF_CREATED callback
alision43a9b362013-05-01 16:30:15 -0400712 }
713 });
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500714 Log.i(TAG, "After joining participants");
alision7f18fc82013-05-01 09:37:33 -0400715 }
716
alision7f18fc82013-05-01 09:37:33 -0400717 @Override
alision806e18e2013-06-21 15:30:17 -0400718 public void addParticipant(final SipCall call, final String confID) throws RemoteException {
alision43a9b362013-05-01 16:30:15 -0400719 getExecutor().execute(new SipRunnable() {
720 @Override
721 protected void doRun() throws SameThreadException, RemoteException {
722 Log.i(TAG, "SipService.addParticipant() thread running...");
alision806e18e2013-06-21 15:30:17 -0400723 callManagerJNI.addParticipant(call.getCallId(), confID);
Alexandre Lision945e4612014-01-15 17:40:31 -0500724 mConferences.get(confID).getParticipants().add(call);
alision43a9b362013-05-01 16:30:15 -0400725 }
726 });
727
alision7f18fc82013-05-01 09:37:33 -0400728 }
729
730 @Override
alision43a9b362013-05-01 16:30:15 -0400731 public void addMainParticipant(final String confID) throws RemoteException {
732 getExecutor().execute(new SipRunnable() {
733 @Override
734 protected void doRun() throws SameThreadException, RemoteException {
735 Log.i(TAG, "SipService.addMainParticipant() thread running...");
736 callManagerJNI.addMainParticipant(confID);
737 }
738 });
739
alision7f18fc82013-05-01 09:37:33 -0400740 }
741
742 @Override
alision43a9b362013-05-01 16:30:15 -0400743 public void detachParticipant(final String callID) throws RemoteException {
744 getExecutor().execute(new SipRunnable() {
745 @Override
746 protected void doRun() throws SameThreadException, RemoteException {
747 Log.i(TAG, "SipService.detachParticipant() thread running...");
alision806e18e2013-06-21 15:30:17 -0400748 Log.i(TAG, "Detaching " + callID);
Alexandre Lision945e4612014-01-15 17:40:31 -0500749 Iterator<Entry<String, Conference>> it = mConferences.entrySet().iterator();
750 Log.i(TAG, "mConferences size " + mConferences.size());
alision806e18e2013-06-21 15:30:17 -0400751 while (it.hasNext()) {
752 Conference tmp = it.next().getValue();
753 Log.i(TAG, "conf has " + tmp.getParticipants().size() + " participants");
754 if (tmp.contains(callID)) {
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500755 Conference toDetach = new Conference(tmp.getCallById(callID));
Alexandre Lision945e4612014-01-15 17:40:31 -0500756 mConferences.put(toDetach.getId(), toDetach);
alision806e18e2013-06-21 15:30:17 -0400757 Log.i(TAG, "Call found and put in current_calls");
758 }
759 }
alision43a9b362013-05-01 16:30:15 -0400760 callManagerJNI.detachParticipant(callID);
761 }
762 });
763
alision7f18fc82013-05-01 09:37:33 -0400764 }
765
766 @Override
alision43a9b362013-05-01 16:30:15 -0400767 public void joinConference(final String sel_confID, final String drag_confID) throws RemoteException {
768 getExecutor().execute(new SipRunnable() {
769 @Override
770 protected void doRun() throws SameThreadException, RemoteException {
771 Log.i(TAG, "SipService.joinConference() thread running...");
772 callManagerJNI.joinConference(sel_confID, drag_confID);
773 }
774 });
775
alision7f18fc82013-05-01 09:37:33 -0400776 }
777
778 @Override
alision43a9b362013-05-01 16:30:15 -0400779 public void hangUpConference(final String confID) throws RemoteException {
780 getExecutor().execute(new SipRunnable() {
781 @Override
782 protected void doRun() throws SameThreadException, RemoteException {
783 Log.i(TAG, "SipService.joinConference() thread running...");
784 callManagerJNI.hangUpConference(confID);
785 }
786 });
787
alision7f18fc82013-05-01 09:37:33 -0400788 }
789
790 @Override
alision43a9b362013-05-01 16:30:15 -0400791 public void holdConference(final String confID) throws RemoteException {
792 getExecutor().execute(new SipRunnable() {
793 @Override
794 protected void doRun() throws SameThreadException, RemoteException {
795 Log.i(TAG, "SipService.holdConference() thread running...");
796 callManagerJNI.holdConference(confID);
797 }
798 });
799
alision7f18fc82013-05-01 09:37:33 -0400800 }
801
802 @Override
alision43a9b362013-05-01 16:30:15 -0400803 public void unholdConference(final String confID) throws RemoteException {
804 getExecutor().execute(new SipRunnable() {
805 @Override
806 protected void doRun() throws SameThreadException, RemoteException {
807 Log.i(TAG, "SipService.unholdConference() thread running...");
808 callManagerJNI.unholdConference(confID);
809 }
810 });
811
alision7f18fc82013-05-01 09:37:33 -0400812 }
Alexandre Lision67817192013-07-18 12:04:30 -0400813
alisioncd8fb912013-06-28 14:43:51 -0400814 @Override
815 public boolean isConferenceParticipant(final String callID) throws RemoteException {
816 class IsParticipant extends SipRunnableWithReturn {
817
818 @Override
819 protected Boolean doRun() throws SameThreadException {
820 Log.i(TAG, "SipService.isRecording() thread running...");
821 return callManagerJNI.isConferenceParticipant(callID);
822 }
823 }
824
825 IsParticipant runInstance = new IsParticipant();
826 getExecutor().execute(runInstance);
827 while (!runInstance.isDone()) {
828 }
829
830 return (Boolean) runInstance.getVal();
831 }
alision7f18fc82013-05-01 09:37:33 -0400832
833 @Override
alisiondf1dac92013-06-27 17:35:53 -0400834 public HashMap<String, Conference> getConferenceList() throws RemoteException {
Alexandre Lision67817192013-07-18 12:04:30 -0400835 // class ConfList extends SipRunnableWithReturn {
836 // @Override
837 // protected StringVect doRun() throws SameThreadException {
838 // Log.i(TAG, "SipService.getConferenceList() thread running...");
839 // return callManagerJNI.getConferenceList();
840 // }
841 // }
842 // ;
843 // ConfList runInstance = new ConfList();
844 // getExecutor().execute(runInstance);
845 // while (!runInstance.isDone()) {
846 // // Log.w(TAG, "Waiting for getConferenceList");
847 // }
848 // StringVect swigvect = (StringVect) runInstance.getVal();
849 //
850 // ArrayList<String> nativelist = new ArrayList<String>();
851 //
852 // for (int i = 0; i < swigvect.size(); i++)
853 // nativelist.add(swigvect.get(i));
854 //
855 // return nativelist;
Alexandre Lision945e4612014-01-15 17:40:31 -0500856 return mConferences;
alision7f18fc82013-05-01 09:37:33 -0400857 }
858
859 @Override
alision907bde72013-06-20 14:40:37 -0400860 public List getParticipantList(final String confID) throws RemoteException {
861 class PartList extends SipRunnableWithReturn {
862 @Override
863 protected StringVect doRun() throws SameThreadException {
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500864 Log.i(TAG, "SipService.getParticipantList() thread running...");
alision907bde72013-06-20 14:40:37 -0400865 return callManagerJNI.getParticipantList(confID);
866 }
867 }
868 ;
869 PartList runInstance = new PartList();
870 getExecutor().execute(runInstance);
871 while (!runInstance.isDone()) {
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500872 Log.w(TAG, "getParticipantList");
alision907bde72013-06-20 14:40:37 -0400873 }
874 StringVect swigvect = (StringVect) runInstance.getVal();
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500875 Log.w(TAG, "After that");
alision907bde72013-06-20 14:40:37 -0400876 ArrayList<String> nativelist = new ArrayList<String>();
877
878 for (int i = 0; i < swigvect.size(); i++)
879 nativelist.add(swigvect.get(i));
880
881 return nativelist;
alision7f18fc82013-05-01 09:37:33 -0400882 }
alision806e18e2013-06-21 15:30:17 -0400883
alision1005ba12013-06-19 13:52:44 -0400884 @Override
alision7f18fc82013-05-01 09:37:33 -0400885 public String getConferenceId(String callID) throws RemoteException {
alision43a9b362013-05-01 16:30:15 -0400886 Log.e(TAG, "getConferenceList not implemented");
alision7f18fc82013-05-01 09:37:33 -0400887 return null;
888 }
889
890 @Override
alision806e18e2013-06-21 15:30:17 -0400891 public String getConferenceDetails(final String callID) throws RemoteException {
892 class ConfDetails extends SipRunnableWithReturn {
893 @Override
894 protected StringMap doRun() throws SameThreadException {
895 Log.i(TAG, "SipService.getAccountList() thread running...");
896 return callManagerJNI.getConferenceDetails(callID);
897 }
898 }
899 ;
900 ConfDetails runInstance = new ConfDetails();
901 getExecutor().execute(runInstance);
902 while (!runInstance.isDone()) {
903 // Log.w(TAG, "Waiting for getConferenceList");
904 }
905 StringMap swigvect = (StringMap) runInstance.getVal();
906
907 return swigvect.get("CONF_STATE");
alision7f18fc82013-05-01 09:37:33 -0400908 }
909
alision04a00182013-05-10 17:05:29 -0400910 @Override
911 public String getRecordPath() throws RemoteException {
912 class RecordPath extends SipRunnableWithReturn {
913
914 @Override
915 protected String doRun() throws SameThreadException {
916 Log.i(TAG, "SipService.getRecordPath() thread running...");
Adrien Béraud9360f242013-09-19 11:07:42 +1000917 return configurationManagerJNI.getRecordPath();
alision04a00182013-05-10 17:05:29 -0400918 }
919 }
920
921 RecordPath runInstance = new RecordPath();
922 getExecutor().execute(runInstance);
923 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400924 // Log.w(TAG, "Waiting for getRecordPath");
alision04a00182013-05-10 17:05:29 -0400925 }
926 String path = (String) runInstance.getVal();
927
928 return path;
929 }
930
931 @Override
Alexandre Lisiona764c682013-09-09 10:02:07 -0400932 public boolean toggleRecordingCall(final String id) throws RemoteException {
Adrien Béraud9360f242013-09-19 11:07:42 +1000933
Alexandre Lisiona764c682013-09-09 10:02:07 -0400934 class ToggleRecording extends SipRunnableWithReturn {
935
alision04a00182013-05-10 17:05:29 -0400936 @Override
Alexandre Lisiona764c682013-09-09 10:02:07 -0400937 protected Boolean doRun() throws SameThreadException {
938 Log.i(TAG, "SipService.toggleRecordingCall() thread running...");
Alexandre Lision3874e552013-11-04 17:20:12 -0500939 boolean result = callManagerJNI.toggleRecording(id);
Alexandre Lision35577132013-12-06 15:21:15 -0500940
Alexandre Lision945e4612014-01-15 17:40:31 -0500941 if (getConferences().containsKey(id)) {
942 getConferences().get(id).setRecording(result);
Alexandre Lision3874e552013-11-04 17:20:12 -0500943 } else {
Alexandre Lision945e4612014-01-15 17:40:31 -0500944 Iterator<Conference> it = getConferences().values().iterator();
Alexandre Lision3874e552013-11-04 17:20:12 -0500945 while (it.hasNext()) {
946 Conference c = it.next();
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500947 if (c.getCallById(id) != null)
948 c.getCallById(id).setRecording(result);
Alexandre Lision3874e552013-11-04 17:20:12 -0500949 }
950 }
951 return result;
alision04a00182013-05-10 17:05:29 -0400952 }
Alexandre Lisiona764c682013-09-09 10:02:07 -0400953 }
954
955 ToggleRecording runInstance = new ToggleRecording();
956 getExecutor().execute(runInstance);
957 while (!runInstance.isDone()) {
958 }
959
960 return (Boolean) runInstance.getVal();
alision04a00182013-05-10 17:05:29 -0400961
962 }
Alexandre Lision67817192013-07-18 12:04:30 -0400963
alision50fa0722013-06-25 17:29:44 -0400964 @Override
965 public boolean startRecordedFilePlayback(final String filepath) throws RemoteException {
966 getExecutor().execute(new SipRunnable() {
967 @Override
968 protected void doRun() throws SameThreadException, RemoteException {
969 Log.i(TAG, "SipService.setRecordingCall() thread running...");
970 callManagerJNI.startRecordedFilePlayback(filepath);
971 }
972 });
973 return false;
974 }
975
976 @Override
977 public void stopRecordedFilePlayback(final String filepath) throws RemoteException {
978 getExecutor().execute(new SipRunnable() {
979 @Override
980 protected void doRun() throws SameThreadException, RemoteException {
981 Log.i(TAG, "SipService.stopRecordedFilePlayback() thread running...");
982 callManagerJNI.stopRecordedFilePlayback(filepath);
983 }
984 });
985 }
alision04a00182013-05-10 17:05:29 -0400986
987 @Override
988 public void setRecordPath(final String path) throws RemoteException {
989 getExecutor().execute(new SipRunnable() {
990 @Override
991 protected void doRun() throws SameThreadException, RemoteException {
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400992 Log.i(TAG, "SipService.setRecordPath() " + path + " thread running...");
Adrien Béraud9360f242013-09-19 11:07:42 +1000993 configurationManagerJNI.setRecordPath(path);
alision04a00182013-05-10 17:05:29 -0400994 }
995 });
996 }
997
998 @Override
Alexandre Lisiond5686032013-10-29 11:09:21 -0400999 public void sendTextMessage(final String callID, final SipMessage message) throws RemoteException {
alision04a00182013-05-10 17:05:29 -04001000 getExecutor().execute(new SipRunnable() {
1001 @Override
1002 protected void doRun() throws SameThreadException, RemoteException {
1003 Log.i(TAG, "SipService.sendTextMessage() thread running...");
Alexandre Lisiond5686032013-10-29 11:09:21 -04001004 callManagerJNI.sendTextMessage(callID, message.comment);
Alexandre Lision945e4612014-01-15 17:40:31 -05001005 if (getConferences().get(callID) != null)
1006 getConferences().get(callID).addSipMessage(message);
alision04a00182013-05-10 17:05:29 -04001007 }
1008 });
1009
1010 }
1011
alisiond295ec22013-05-17 10:12:13 -04001012 @Override
Alexandre Lision4cf78702013-10-16 13:43:23 -04001013 public List getAudioCodecList(final String accountID) throws RemoteException {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001014 class AudioCodecList extends SipRunnableWithReturn {
1015
1016 @Override
Alexandre Lision933ef0a2013-10-15 17:28:40 -04001017 protected ArrayList<Codec> doRun() throws SameThreadException {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001018 Log.i(TAG, "SipService.getAudioCodecList() thread running...");
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001019 ArrayList<Codec> results = new ArrayList<Codec>();
Alexandre Lision4cf78702013-10-16 13:43:23 -04001020
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001021 IntVect active_payloads = configurationManagerJNI.getActiveAudioCodecList(accountID);
1022 for (int i = 0; i < active_payloads.size(); ++i) {
1023
Alexandre Lision039a3cf2013-10-16 17:44:57 -04001024 results.add(new Codec(active_payloads.get(i), configurationManagerJNI.getAudioCodecDetails(active_payloads.get(i)), true));
Alexandre Lisione0045442013-10-25 09:16:19 -04001025
Alexandre Lision4cf78702013-10-16 13:43:23 -04001026 }
Alexandre Lision039a3cf2013-10-16 17:44:57 -04001027 IntVect payloads = configurationManagerJNI.getAudioCodecList();
1028
1029 for (int i = 0; i < payloads.size(); ++i) {
1030 boolean isActive = false;
1031 for (Codec co : results) {
1032 if (co.getPayload().toString().contentEquals(String.valueOf(payloads.get(i))))
1033 isActive = true;
1034
1035 }
1036 if (isActive)
1037 continue;
1038 else
1039 results.add(new Codec(payloads.get(i), configurationManagerJNI.getAudioCodecDetails(payloads.get(i)), false));
1040
1041 }
1042
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001043 return results;
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001044 }
1045 }
1046
1047 AudioCodecList runInstance = new AudioCodecList();
1048 getExecutor().execute(runInstance);
1049 while (!runInstance.isDone()) {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001050 }
Alexandre Lision933ef0a2013-10-15 17:28:40 -04001051 ArrayList<Codec> codecs = (ArrayList<Codec>) runInstance.getVal();
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001052 return codecs;
alisiond295ec22013-05-17 10:12:13 -04001053 }
1054
alision9f7a6ec2013-05-24 16:26:26 -04001055 @Override
Alexandre Lision4cf78702013-10-16 13:43:23 -04001056 public Map getRingtoneList() throws RemoteException {
1057 class RingtoneList extends SipRunnableWithReturn {
1058
1059 @Override
1060 protected StringMap doRun() throws SameThreadException {
1061 Log.i(TAG, "SipService.getRingtoneList() thread running...");
1062 return configurationManagerJNI.getRingtoneList();
1063 }
1064 }
1065
1066 RingtoneList runInstance = new RingtoneList();
1067 getExecutor().execute(runInstance);
1068 while (!runInstance.isDone()) {
1069 }
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001070 StringMap ringtones = (StringMap) runInstance.getVal();
1071
1072 for (int i = 0; i < ringtones.size(); ++i) {
1073 // Log.i(TAG,"ringtones "+i+" "+ ringtones.);
1074 }
1075
Alexandre Lision4cf78702013-10-16 13:43:23 -04001076 return null;
1077 }
1078
1079 @Override
1080 public void setActiveCodecList(final List codecs, final String accountID) throws RemoteException {
1081 getExecutor().execute(new SipRunnable() {
1082 @Override
1083 protected void doRun() throws SameThreadException, RemoteException {
1084 Log.i(TAG, "SipService.setActiveAudioCodecList() thread running...");
1085 StringVect list = new StringVect();
1086 for (int i = 0; i < codecs.size(); ++i) {
1087 list.add((String) codecs.get(i));
1088 }
1089 configurationManagerJNI.setActiveAudioCodecList(list, accountID);
1090 }
1091 });
1092 }
1093
alision2cb99562013-05-30 17:02:20 -04001094 /***********************
1095 * Notification API
1096 ***********************/
1097 @Override
1098 public void createNotification() throws RemoteException {
alisioncc7bb422013-06-06 15:31:39 -04001099
alision2cb99562013-05-30 17:02:20 -04001100 }
1101
1102 @Override
1103 public void destroyNotification() throws RemoteException {
alisioncc7bb422013-06-06 15:31:39 -04001104
alision2cb99562013-05-30 17:02:20 -04001105 }
alisioncc7bb422013-06-06 15:31:39 -04001106
alisiondf1dac92013-06-27 17:35:53 -04001107 @Override
1108 public Conference getCurrentCall() throws RemoteException {
Alexandre Lision945e4612014-01-15 17:40:31 -05001109 for (Conference conf : mConferences.values()) {
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -05001110 if (conf.isIncoming())
1111 return conf;
alisiondf1dac92013-06-27 17:35:53 -04001112 }
Alexandre Lision67817192013-07-18 12:04:30 -04001113
Alexandre Lision945e4612014-01-15 17:40:31 -05001114 for (Conference conf : mConferences.values()) {
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -05001115 if (conf.isOnGoing())
1116 return conf;
alisiondf1dac92013-06-27 17:35:53 -04001117 }
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -05001118
alisiondf1dac92013-06-27 17:35:53 -04001119 return null;
1120 }
1121
Alexandre Lision64dc8c02013-09-25 15:32:25 -04001122 @Override
1123 public void playDtmf(final String key) throws RemoteException {
1124 getExecutor().execute(new SipRunnable() {
1125 @Override
1126 protected void doRun() throws SameThreadException, RemoteException {
1127 Log.i(TAG, "SipService.playDtmf() thread running...");
1128 callManagerJNI.playDTMF(key);
1129 }
1130 });
1131 }
1132
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001133 @Override
1134 public List getConcurrentCalls() throws RemoteException {
Alexandre Lision945e4612014-01-15 17:40:31 -05001135 return new ArrayList(mConferences.values());
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -05001136 }
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001137
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -05001138 @Override
1139 public Conference getConference(String id) throws RemoteException {
Alexandre Lision945e4612014-01-15 17:40:31 -05001140 return mConferences.get(id);
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001141 }
1142
Alexandre Lision4fb22622013-10-21 16:26:33 -04001143 @Override
1144 public String getCurrentAudioCodecName(String callID) throws RemoteException {
1145 return callManagerJNI.getCurrentAudioCodecName(callID);
1146 }
1147
Alexandre Lision31e30902013-11-08 15:16:59 -05001148 @Override
1149 public void setMuted(final boolean mute) throws RemoteException {
1150 getExecutor().execute(new SipRunnable() {
1151 @Override
1152 protected void doRun() throws SameThreadException, RemoteException {
1153 Log.i(TAG, "SipService.setMuted() thread running...");
1154 configurationManagerJNI.muteCapture(mute);
1155 }
1156 });
1157 }
1158
1159 @Override
1160 public boolean isCaptureMuted() throws RemoteException {
1161 class IsMuted extends SipRunnableWithReturn {
1162
1163 @Override
1164 protected Boolean doRun() throws SameThreadException {
1165 Log.i(TAG, "SipService.isCaptureMuted() thread running...");
1166 return configurationManagerJNI.isCaptureMuted();
1167 }
1168 }
1169
1170 IsMuted runInstance = new IsMuted();
1171 getExecutor().execute(runInstance);
1172 while (!runInstance.isDone()) {
1173 }
1174
1175 return (Boolean) runInstance.getVal();
1176 }
1177
Alexandre Lision3b7148e2013-11-13 17:23:06 -05001178 @Override
Alexandre Lision48b49eb2014-02-11 13:37:33 -05001179 public void confirmSAS(final String callID) throws RemoteException {
1180 getExecutor().execute(new SipRunnable() {
1181 @Override
1182 protected void doRun() throws SameThreadException, RemoteException {
1183 Log.i(TAG, "SipService.confirmSAS() thread running...");
Alexandre Lision1b932d82014-02-21 10:03:19 -05001184 SecureSipCall call = (SecureSipCall) getCallById(callID);
Alexandre Lision651b5262014-02-21 17:14:14 -05001185 call.setSASConfirmed(true);
Alexandre Lision48b49eb2014-02-11 13:37:33 -05001186 callManagerJNI.setSASVerified(callID);
1187 }
1188 });
1189 }
1190
1191 @Override
Alexandre Lision3b7148e2013-11-13 17:23:06 -05001192 public List getCredentials(final String accountID) throws RemoteException {
1193 class Credentials extends SipRunnableWithReturn {
1194
1195 @Override
1196 protected List doRun() throws SameThreadException {
1197 Log.i(TAG, "SipService.getCredentials() thread running...");
1198 VectMap map = configurationManagerJNI.getCredentials(accountID);
Alexandre Lision2aae48d2013-12-04 13:50:38 -05001199 ArrayList<HashMap<String, String>> result = SwigNativeConverter.convertCredentialsToNative(map);
Alexandre Lision3b7148e2013-11-13 17:23:06 -05001200 return result;
1201 }
1202 }
1203
1204 Credentials runInstance = new Credentials();
1205 getExecutor().execute(runInstance);
1206 while (!runInstance.isDone()) {
1207 }
1208 return (List) runInstance.getVal();
1209 }
1210
1211 @Override
1212 public void setCredentials(final String accountID, final List creds) throws RemoteException {
1213 getExecutor().execute(new SipRunnable() {
1214 @Override
1215 protected void doRun() throws SameThreadException, RemoteException {
1216 Log.i(TAG, "SipService.setCredentials() thread running...");
Alexandre Lision3cefec22013-11-14 17:26:35 -05001217 ArrayList<HashMap<String, String>> list = (ArrayList<HashMap<String, String>>) creds;
Alexandre Lision2aae48d2013-12-04 13:50:38 -05001218 configurationManagerJNI.setCredentials(accountID, SwigNativeConverter.convertFromNativeToSwig(creds));
Alexandre Lision3b7148e2013-11-13 17:23:06 -05001219 }
1220 });
1221 }
1222
Alexandre Lision3e2a1d02013-11-19 17:23:00 -05001223 @Override
1224 public void registerAllAccounts() throws RemoteException {
1225 getExecutor().execute(new SipRunnable() {
1226 @Override
1227 protected void doRun() throws SameThreadException, RemoteException {
1228 Log.i(TAG, "SipService.registerAllAccounts() thread running...");
1229 configurationManagerJNI.registerAllAccounts();
1230 }
1231 });
1232 }
1233
Alexandre Lision5f733bc2013-12-04 13:10:30 -05001234 @Override
Alexandre Lision35577132013-12-06 15:21:15 -05001235 public void toggleSpeakerPhone(boolean toggle) throws RemoteException {
1236 if (toggle)
Alexandre Lision945e4612014-01-15 17:40:31 -05001237 mMediaManager.RouteToSpeaker();
Alexandre Lision35577132013-12-06 15:21:15 -05001238 else
Alexandre Lision945e4612014-01-15 17:40:31 -05001239 mMediaManager.RouteToInternalSpeaker();
Alexandre Lision5f733bc2013-12-04 13:10:30 -05001240 }
1241
Emeric Vigier6119d782012-09-21 18:04:14 -04001242 };
Alexandre Lision3c37dca2014-02-21 14:13:26 -05001243
1244 private void removeCall(String callID) {
1245 Conference conf = findConference(callID);
1246 if(conf == null)
1247 return;
1248 if(conf.getParticipants().size() == 1)
1249 getConferences().remove(conf.getId());
1250 else
1251 conf.removeParticipant(conf.getCallById(callID));
1252 }
1253
1254 protected Conference findConference(String callID) {
1255 Conference result = null;
1256 if (getConferences().get(callID) != null) {
1257 result = getConferences().get(callID);
1258 } else {
1259 Iterator<Map.Entry<String, Conference>> it = getConferences().entrySet().iterator();
1260 while (it.hasNext()) {
1261 Conference tmp = it.next().getValue();
1262 for (SipCall c : tmp.getParticipants()) {
1263 if (c.getCallId().contentEquals(callID)) {
1264 result = tmp;
1265 }
1266 }
1267 }
1268 }
1269 return result;
1270 }
Alexandre Lision35577132013-12-06 15:21:15 -05001271}