blob: 9fb404b8f359ec7b6d8c28b376898e949844846d [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 Lision945e4612014-01-15 17:40:31 -050034import org.sflphone.history.HistoryManager;
Alexandre Lisiona7ab2e32014-02-14 15:33:33 -050035import org.sflphone.model.*;
Alexandre Lision6d867b92013-10-25 15:36:28 -040036import org.sflphone.utils.MediaManager;
Alexandre Lisione0045442013-10-25 09:16:19 -040037import org.sflphone.utils.SipNotifications;
Alexandre Lision2aae48d2013-12-04 13:50:38 -050038import org.sflphone.utils.SwigNativeConverter;
Alexandre Lision064e1e02013-10-01 16:18:42 -040039
Emeric Vigiereaf2c492012-09-19 14:38:20 -040040import android.app.Service;
41import android.content.Intent;
alision7f18fc82013-05-01 09:37:33 -040042import android.os.Bundle;
Emeric Vigier6119d782012-09-21 18:04:14 -040043import android.os.Handler;
44import android.os.HandlerThread;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040045import android.os.IBinder;
Emeric Vigier6119d782012-09-21 18:04:14 -040046import android.os.Looper;
47import android.os.Message;
alision5f899632013-04-22 17:26:56 -040048import android.os.RemoteException;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040049import android.util.Log;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040050
Emeric Vigiereaf2c492012-09-19 14:38:20 -040051public class SipService extends Service {
52
53 static final String TAG = "SipService";
Emeric Vigier6119d782012-09-21 18:04:14 -040054 private SipServiceExecutor mExecutor;
55 private static HandlerThread executorThread;
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -050056
alision3ea8f3c2013-07-16 17:35:35 -040057 private CallManager callManagerJNI;
Alexandre Lision67817192013-07-18 12:04:30 -040058 private ManagerImpl managerImpl;
Emeric Vigier0007dee2012-09-24 11:35:58 -040059 private CallManagerCallBack callManagerCallBack;
Alexandre Lisionb2669692014-01-28 14:06:08 -050060
alision3ea8f3c2013-07-16 17:35:35 -040061 private ConfigurationManager configurationManagerJNI;
Alexandre Savardfccd1dc2012-10-17 17:31:38 -040062 private ConfigurationManagerCallback configurationManagerCallback;
Emeric Vigier6119d782012-09-21 18:04:14 -040063 private boolean isPjSipStackStarted = false;
alisioncc7bb422013-06-06 15:31:39 -040064
Alexandre Lision945e4612014-01-15 17:40:31 -050065 protected SipNotifications mNotificationManager;
66 protected HistoryManager mHistoryManager;
67 protected MediaManager mMediaManager;
Alexandre Lisione0045442013-10-25 09:16:19 -040068
Alexandre Lision945e4612014-01-15 17:40:31 -050069 private HashMap<String, Conference> mConferences = new HashMap<String, Conference>();
Emeric Vigier6119d782012-09-21 18:04:14 -040070
Alexandre Lision945e4612014-01-15 17:40:31 -050071 public HashMap<String, Conference> getConferences() {
72 return mConferences;
alision806e18e2013-06-21 15:30:17 -040073 }
alision43a9b362013-05-01 16:30:15 -040074
Alexandre Lisionb2669692014-01-28 14:06:08 -050075 public CallManager getCallManagerJNI() {
76 return callManagerJNI;
77 }
78
79 public ConfigurationManager getConfigurationManagerJNI() {
80 return configurationManagerJNI;
81 }
82
Alexandre Lision183bf452014-01-17 11:21:59 -050083 public void addCallToConference(String confId, String callId) {
84 if(mConferences.get(callId) != null){
85 // We add a simple call to a conference
Alexandre Lision96db8032014-01-17 16:43:51 -050086 Log.i(TAG, "// We add a simple call to a conference");
Alexandre Lision183bf452014-01-17 11:21:59 -050087 mConferences.get(confId).addParticipant(mConferences.get(callId).getParticipants().get(0));
88 mConferences.remove(callId);
89 } else {
Alexandre Lision96db8032014-01-17 16:43:51 -050090 Log.i(TAG, "addCallToConference");
Alexandre Lision183bf452014-01-17 11:21:59 -050091 Iterator<Map.Entry<String, Conference>> it = mConferences.entrySet().iterator();
92 while (it.hasNext()) {
93 Conference tmp = it.next().getValue();
94 for (SipCall c : tmp.getParticipants()) {
95 if (c.getCallId().contentEquals(callId)) {
96 mConferences.get(confId).addParticipant(c);
Alexandre Lision96db8032014-01-17 16:43:51 -050097 mConferences.get(tmp.getId()).removeParticipant(c);
Alexandre Lision183bf452014-01-17 11:21:59 -050098 }
99 }
100 }
101 }
102
103 }
104
Alexandre Lision96db8032014-01-17 16:43:51 -0500105 public void detachCallFromConference(String confId, SipCall call) {
106 Log.i(TAG, "detachCallFromConference");
Alexandre Lision183bf452014-01-17 11:21:59 -0500107 Conference separate = new Conference(call);
108 mConferences.put(separate.getId(), separate);
Alexandre Lision96db8032014-01-17 16:43:51 -0500109 mConferences.get(confId).removeParticipant(call);
Alexandre Lision183bf452014-01-17 11:21:59 -0500110 }
111
112
alision43a9b362013-05-01 16:30:15 -0400113 @Override
114 public boolean onUnbind(Intent i) {
115 super.onUnbind(i);
116 Log.i(TAG, "onUnbind(intent)");
Alexandre Lision0f550ee2013-10-25 15:34:38 -0400117 return true;
118 }
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400119
Alexandre Lision0f550ee2013-10-25 15:34:38 -0400120 @Override
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400121 public void onRebind(Intent i) {
Alexandre Lision0f550ee2013-10-25 15:34:38 -0400122 super.onRebind(i);
alision43a9b362013-05-01 16:30:15 -0400123 }
124
125 /* called once by startService() */
126 @Override
127 public void onCreate() {
128 Log.i(TAG, "onCreated");
129 super.onCreate();
130
alisioncc7bb422013-06-06 15:31:39 -0400131 getExecutor().execute(new StartRunnable());
Alexandre Lisione0045442013-10-25 09:16:19 -0400132
Alexandre Lision945e4612014-01-15 17:40:31 -0500133 mNotificationManager = new SipNotifications(this);
134 mMediaManager = new MediaManager(this);
135 mHistoryManager = new HistoryManager(this);
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400136
Alexandre Lision945e4612014-01-15 17:40:31 -0500137 mNotificationManager.onServiceCreate();
138 mMediaManager.startService();
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400139
alisioncc7bb422013-06-06 15:31:39 -0400140 }
alision43a9b362013-05-01 16:30:15 -0400141
142 /* called for each startService() */
143 @Override
144 public int onStartCommand(Intent intent, int flags, int startId) {
145 Log.i(TAG, "onStarted");
146 super.onStartCommand(intent, flags, startId);
Alexandre Lision0f550ee2013-10-25 15:34:38 -0400147 return START_STICKY; /* started and stopped explicitly */
alision43a9b362013-05-01 16:30:15 -0400148 }
149
150 @Override
151 public void onDestroy() {
Alexandre Lision52214992013-10-28 17:41:23 -0400152 Log.i(TAG, "onDestroy");
alision43a9b362013-05-01 16:30:15 -0400153 /* called once by stopService() */
Alexandre Lision945e4612014-01-15 17:40:31 -0500154 mNotificationManager.onServiceDestroy();
Alexandre Lision183bf452014-01-17 11:21:59 -0500155 mMediaManager.stopService();
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400156 getExecutor().execute(new FinalizeRunnable());
alision43a9b362013-05-01 16:30:15 -0400157 super.onDestroy();
158
alision43a9b362013-05-01 16:30:15 -0400159 }
160
161 @Override
162 public IBinder onBind(Intent arg0) {
163 Log.i(TAG, "onBound");
164 return mBinder;
165 }
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400166
alision43a9b362013-05-01 16:30:15 -0400167 private static Looper createLooper() {
168 if (executorThread == null) {
169 Log.d(TAG, "Creating new handler thread");
170 // ADT gives a fake warning due to bad parse rule.
171 executorThread = new HandlerThread("SipService.Executor");
172 executorThread.start();
173 }
174 return executorThread.getLooper();
175 }
176
177 public SipServiceExecutor getExecutor() {
178 // create mExecutor lazily
179 if (mExecutor == null) {
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500180 mExecutor = new SipServiceExecutor();
alision43a9b362013-05-01 16:30:15 -0400181 }
182 return mExecutor;
183 }
184
Alexandre Lision5f144b82014-02-11 09:59:36 -0500185 public SipCall getCallById(String callID) {
186 if (getConferences().get(callID) != null) {
187 return getConferences().get(callID).getCallById(callID);
188 } else {
189 // Check if call is in a conference
190 Iterator<Map.Entry<String, Conference>> it = getConferences().entrySet().iterator();
191 while (it.hasNext()) {
192 Conference tmp = it.next().getValue();
193 SipCall c = tmp.getCallById(callID);
194 if(c != null)
195 return c;
196 }
197 }
198 return null;
199 }
200
Alexandre Lisiona7ab2e32014-02-14 15:33:33 -0500201 /*
202 *
203 * Used when we need to transform a SipCall in a SecureSipCall or vice versa
204 *
205 * */
206 public void replaceCall(SipCall replace) {
207 if (getConferences().get(replace.getCallId()) != null) {
208 getConferences().get(replace.getCallId()).removeParticipant(replace);
209 getConferences().get(replace.getCallId()).addParticipant(replace);
210 } else {
211 // Check if call is in a conference
212 Iterator<Map.Entry<String, Conference>> it = getConferences().entrySet().iterator();
213 while (it.hasNext()) {
214 Conference tmp = it.next().getValue();
215 SipCall c = tmp.getCallById(replace.getCallId());
216 if(c != null){
217 tmp.removeParticipant(c);
218 tmp.addParticipant(replace);
219 return;
220 }
221 }
222 }
223 }
224
alision43a9b362013-05-01 16:30:15 -0400225 // Executes immediate tasks in a single executorThread.
226 public static class SipServiceExecutor extends Handler {
alision43a9b362013-05-01 16:30:15 -0400227
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500228 SipServiceExecutor() {
alision43a9b362013-05-01 16:30:15 -0400229 super(createLooper());
alision43a9b362013-05-01 16:30:15 -0400230 }
231
232 public void execute(Runnable task) {
233 // TODO: add wakelock
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500234 Message.obtain(SipServiceExecutor.this, 0/* don't care */, task).sendToTarget();
Alexandre Lisioncdec5952013-07-17 14:18:22 -0400235 Log.w(TAG, "SenT!");
alision43a9b362013-05-01 16:30:15 -0400236 }
237
238 @Override
239 public void handleMessage(Message msg) {
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500240 Log.w(TAG, "handleMessage");
alision43a9b362013-05-01 16:30:15 -0400241 if (msg.obj instanceof Runnable) {
242 executeInternal((Runnable) msg.obj);
243 } else {
244 Log.w(TAG, "can't handle msg: " + msg);
245 }
246 }
247
248 private void executeInternal(Runnable task) {
249 try {
250 task.run();
251 } catch (Throwable t) {
252 Log.e(TAG, "run task: " + task, t);
253 }
254 }
255 }
Alexandre Lision63870a72013-10-28 16:33:47 -0400256
257 private void stopDaemon() {
258 if (managerImpl != null) {
259 managerImpl.finish();
260 isPjSipStackStarted = false;
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400261 }
262 }
alision43a9b362013-05-01 16:30:15 -0400263
264 private void startPjSipStack() throws SameThreadException {
265 if (isPjSipStackStarted)
266 return;
267
268 try {
269 System.loadLibrary("gnustl_shared");
alision43a9b362013-05-01 16:30:15 -0400270 System.loadLibrary("crypto");
271 System.loadLibrary("ssl");
alision43a9b362013-05-01 16:30:15 -0400272 System.loadLibrary("sflphone");
273 isPjSipStackStarted = true;
Adrien Béraud9360f242013-09-19 11:07:42 +1000274
alision43a9b362013-05-01 16:30:15 -0400275 } catch (UnsatisfiedLinkError e) {
276 Log.e(TAG, "Problem with the current Pj stack...", e);
277 isPjSipStackStarted = false;
278 return;
279 } catch (Exception e) {
280 Log.e(TAG, "Problem with the current Pj stack...", e);
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400281 isPjSipStackStarted = false;
alision43a9b362013-05-01 16:30:15 -0400282 }
283
Alexandre Lision67817192013-07-18 12:04:30 -0400284 Log.i(TAG, "PjSIPStack started");
285 managerImpl = SFLPhoneservice.instance();
286
287 /* set static AppPath before calling manager.init */
Alexandre Lision63870a72013-10-28 16:33:47 -0400288 // managerImpl.setPath(getApplication().getFilesDir().getAbsolutePath());
alision43a9b362013-05-01 16:30:15 -0400289
alision3ea8f3c2013-07-16 17:35:35 -0400290 callManagerJNI = new CallManager();
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500291 callManagerCallBack = new CallManagerCallBack(this);
alision43a9b362013-05-01 16:30:15 -0400292 SFLPhoneservice.setCallbackObject(callManagerCallBack);
293
alision3ea8f3c2013-07-16 17:35:35 -0400294 configurationManagerJNI = new ConfigurationManager();
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500295 configurationManagerCallback = new ConfigurationManagerCallback(this);
alision43a9b362013-05-01 16:30:15 -0400296 SFLPhoneservice.setConfigurationCallbackObject(configurationManagerCallback);
Alexandre Lision67817192013-07-18 12:04:30 -0400297 managerImpl.init("");
Adrien Béraud9360f242013-09-19 11:07:42 +1000298
Alexandre Lision67817192013-07-18 12:04:30 -0400299 Log.i(TAG, "->startPjSipStack");
alision43a9b362013-05-01 16:30:15 -0400300 }
301
302 // Enforce same thread contract to ensure we do not call from somewhere else
303 public class SameThreadException extends Exception {
304 private static final long serialVersionUID = -905639124232613768L;
305
306 public SameThreadException() {
307 super("Should be launched from a single worker thread");
308 }
309 }
310
311 public abstract static class SipRunnable implements Runnable {
312 protected abstract void doRun() throws SameThreadException, RemoteException;
313
Adrien Béraud9360f242013-09-19 11:07:42 +1000314 @Override
alision43a9b362013-05-01 16:30:15 -0400315 public void run() {
316 try {
317 doRun();
318 } catch (SameThreadException e) {
319 Log.e(TAG, "Not done from same thread");
320 } catch (RemoteException e) {
321 Log.e(TAG, e.toString());
322 }
323 }
324 }
325
Alexandre Lisionfab23f82013-11-01 11:22:30 -0400326 public abstract class SipRunnableWithReturn implements Runnable {
alision43a9b362013-05-01 16:30:15 -0400327 Object obj = null;
328 boolean done = false;
329
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500330 protected abstract Object doRun() throws SameThreadException, RemoteException;
alision43a9b362013-05-01 16:30:15 -0400331
332 public Object getVal() {
333 return obj;
334 }
335
336 public boolean isDone() {
337 return done;
338 }
339
Adrien Béraud9360f242013-09-19 11:07:42 +1000340 @Override
alision43a9b362013-05-01 16:30:15 -0400341 public void run() {
342 try {
Alexandre Lision35577132013-12-06 15:21:15 -0500343 if (isPjSipStackStarted)
Alexandre Lisionfab23f82013-11-01 11:22:30 -0400344 obj = doRun();
alision43a9b362013-05-01 16:30:15 -0400345 done = true;
346 } catch (SameThreadException e) {
347 Log.e(TAG, "Not done from same thread");
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500348 } catch (RemoteException e) {
349 Log.e(TAG, e.toString());
alision43a9b362013-05-01 16:30:15 -0400350 }
351 }
352 }
353
354 class StartRunnable extends SipRunnable {
355 @Override
356 protected void doRun() throws SameThreadException {
357 startPjSipStack();
358 }
359 }
Alexandre Lision63870a72013-10-28 16:33:47 -0400360
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400361 class FinalizeRunnable extends SipRunnable {
362 @Override
363 protected void doRun() throws SameThreadException {
364 stopDaemon();
365 }
366 }
alision43a9b362013-05-01 16:30:15 -0400367
alision43a9b362013-05-01 16:30:15 -0400368 /* ************************************
369 *
370 * Implement public interface for the service
371 *
Alexandre Lision67817192013-07-18 12:04:30 -0400372 * *********************************
373 */
374
Emeric Vigier6119d782012-09-21 18:04:14 -0400375 private final ISipService.Stub mBinder = new ISipService.Stub() {
376
377 @Override
alisionfde875f2013-05-28 17:01:54 -0400378 public void placeCall(final SipCall call) {
Alexandre Lisiona7ab2e32014-02-14 15:33:33 -0500379
Emeric Vigier6119d782012-09-21 18:04:14 -0400380 getExecutor().execute(new SipRunnable() {
381 @Override
382 protected void doRun() throws SameThreadException {
383 Log.i(TAG, "SipService.placeCall() thread running...");
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500384 Conference toAdd = new Conference(call);
Alexandre Lision945e4612014-01-15 17:40:31 -0500385 mConferences.put(toAdd.getId(), toAdd);
386 mMediaManager.obtainAudioFocus(false);
Alexandre Lisiona7ab2e32014-02-14 15:33:33 -0500387 callManagerJNI.placeCall(call.getAccount().getAccountID(), call.getCallId(), call.getmContact().getPhones().get(0).getNumber());
Emeric Vigier6119d782012-09-21 18:04:14 -0400388 }
389 });
390 }
391
392 @Override
393 public void refuse(final String callID) {
Alexandre Lisionf02190d2013-12-12 17:26:12 -0500394
Emeric Vigier6119d782012-09-21 18:04:14 -0400395 getExecutor().execute(new SipRunnable() {
396 @Override
397 protected void doRun() throws SameThreadException {
398 Log.i(TAG, "SipService.refuse() thread running...");
399 callManagerJNI.refuse(callID);
400 }
401 });
402 }
403
404 @Override
405 public void accept(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 {
Tristan Matthews40cf25e2013-07-24 13:45:15 -0400410 Log.i(TAG, "SipService.accept() thread running...");
Emeric Vigier6119d782012-09-21 18:04:14 -0400411 callManagerJNI.accept(callID);
Alexandre Lision945e4612014-01-15 17:40:31 -0500412 mMediaManager.RouteToInternalSpeaker();
Emeric Vigier6119d782012-09-21 18:04:14 -0400413 }
414 });
415 }
416
417 @Override
418 public void hangUp(final String callID) {
Alexandre Lision945e4612014-01-15 17:40:31 -0500419 mMediaManager.stopRing();
Emeric Vigier6119d782012-09-21 18:04:14 -0400420 getExecutor().execute(new SipRunnable() {
421 @Override
422 protected void doRun() throws SameThreadException {
423 Log.i(TAG, "SipService.hangUp() thread running...");
424 callManagerJNI.hangUp(callID);
Alexandre Lision3c37dca2014-02-21 14:13:26 -0500425 removeCall(callID);
426 Log.i(TAG, "mConferences.size():"+mConferences.size());
427 if(mConferences.size() == 0) {
428 Log.i(TAG, "No more calls!");
Alexandre Lision183bf452014-01-17 11:21:59 -0500429 mMediaManager.abandonAudioFocus();
Alexandre Lision3c37dca2014-02-21 14:13:26 -0500430 }
Emeric Vigier6119d782012-09-21 18:04:14 -0400431 }
432 });
433 }
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400434
435 @Override
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400436 public void hold(final String callID) {
437 getExecutor().execute(new SipRunnable() {
438 @Override
439 protected void doRun() throws SameThreadException {
440 Log.i(TAG, "SipService.hold() thread running...");
441 callManagerJNI.hold(callID);
442 }
443 });
444 }
445
446 @Override
447 public void unhold(final String callID) {
448 getExecutor().execute(new SipRunnable() {
449 @Override
450 protected void doRun() throws SameThreadException {
451 Log.i(TAG, "SipService.unhold() thread running...");
452 callManagerJNI.unhold(callID);
453 }
454 });
455 }
Adrien Béraud9360f242013-09-19 11:07:42 +1000456
Alexandre Lision6711ab22013-09-16 15:15:38 -0400457 @Override
458 public HashMap<String, String> getCallDetails(String callID) throws RemoteException {
459 class CallDetails extends SipRunnableWithReturn {
460 private String id;
461
462 CallDetails(String callID) {
463 id = callID;
464 }
465
466 @Override
467 protected StringMap doRun() throws SameThreadException {
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400468 Log.i(TAG, "SipService.getCallDetails() thread running...");
Alexandre Lision6711ab22013-09-16 15:15:38 -0400469 return callManagerJNI.getCallDetails(id);
470 }
471 }
472
473 CallDetails runInstance = new CallDetails(callID);
474 getExecutor().execute(runInstance);
475
476 while (!runInstance.isDone()) {
477 }
478 StringMap swigmap = (StringMap) runInstance.getVal();
479
Alexandre Lision2aae48d2013-12-04 13:50:38 -0500480 HashMap<String, String> nativemap = SwigNativeConverter.convertCallDetailsToNative(swigmap);
Alexandre Lision6711ab22013-09-16 15:15:38 -0400481
482 return nativemap;
Adrien Béraud9360f242013-09-19 11:07:42 +1000483
Alexandre Lision6711ab22013-09-16 15:15:38 -0400484 }
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400485
486 @Override
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400487 public void setAudioPlugin(final String audioPlugin) {
488 getExecutor().execute(new SipRunnable() {
alision371b77e2013-04-23 14:51:26 -0400489 @Override
490 protected void doRun() throws SameThreadException {
491 Log.i(TAG, "SipService.setAudioPlugin() thread running...");
492 configurationManagerJNI.setAudioPlugin(audioPlugin);
493 }
Alexandre Savard31d27c62012-10-04 16:05:08 -0400494 });
495 }
496
497 @Override
498 public String getCurrentAudioOutputPlugin() {
499 class CurrentAudioPlugin extends SipRunnableWithReturn {
500 @Override
501 protected String doRun() throws SameThreadException {
502 Log.i(TAG, "SipService.getCurrentAudioOutputPlugin() thread running...");
503 return configurationManagerJNI.getCurrentAudioOutputPlugin();
504 }
alision371b77e2013-04-23 14:51:26 -0400505 }
506 ;
Alexandre Savard31d27c62012-10-04 16:05:08 -0400507
508 CurrentAudioPlugin runInstance = new CurrentAudioPlugin();
509 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400510 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400511 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400512 }
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400513 return (String) runInstance.getVal();
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400514 }
Alexandre Savard713a34d2012-09-26 15:50:41 -0400515
516 @Override
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400517 public ArrayList<String> getAccountList() {
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400518 class AccountList extends SipRunnableWithReturn {
519 @Override
520 protected StringVect doRun() throws SameThreadException {
521 Log.i(TAG, "SipService.getAccountList() thread running...");
522 return configurationManagerJNI.getAccountList();
523 }
alision371b77e2013-04-23 14:51:26 -0400524 }
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400525 AccountList runInstance = new AccountList();
Alexandre Lisioncdec5952013-07-17 14:18:22 -0400526 Log.i(TAG, "SipService.getAccountList() thread running...");
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400527 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400528 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400529 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400530 }
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400531 StringVect swigvect = (StringVect) runInstance.getVal();
532
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400533 ArrayList<String> nativelist = new ArrayList<String>();
Alexandre Savard52a72522012-09-27 16:40:13 -0400534
alision371b77e2013-04-23 14:51:26 -0400535 for (int i = 0; i < swigvect.size(); i++)
536 nativelist.add(swigvect.get(i));
Alexandre Savard52a72522012-09-27 16:40:13 -0400537
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400538 return nativelist;
alision371b77e2013-04-23 14:51:26 -0400539 }
Alexandre Lision4b4233a2013-10-16 17:24:17 -0400540
Alexandre Lision4cf78702013-10-16 13:43:23 -0400541 @Override
Alexandre Lision4b4233a2013-10-16 17:24:17 -0400542 public void setAccountOrder(final String order) {
Alexandre Lision4cf78702013-10-16 13:43:23 -0400543 getExecutor().execute(new SipRunnable() {
544 @Override
545 protected void doRun() throws SameThreadException {
546 Log.i(TAG, "SipService.setAccountsOrder() thread running...");
547 configurationManagerJNI.setAccountsOrder(order);
548 }
549 });
550 }
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400551
552 @Override
alision371b77e2013-04-23 14:51:26 -0400553 public HashMap<String, String> getAccountDetails(final String accountID) {
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400554 class AccountDetails extends SipRunnableWithReturn {
555 private String id;
alision371b77e2013-04-23 14:51:26 -0400556
557 AccountDetails(String accountId) {
558 id = accountId;
559 }
560
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400561 @Override
562 protected StringMap doRun() throws SameThreadException {
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400563 Log.i(TAG, "SipService.getAccountDetails() thread running...");
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400564 return configurationManagerJNI.getAccountDetails(id);
565 }
alision371b77e2013-04-23 14:51:26 -0400566 }
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400567
568 AccountDetails runInstance = new AccountDetails(accountID);
569 getExecutor().execute(runInstance);
alisionfde875f2013-05-28 17:01:54 -0400570
alision371b77e2013-04-23 14:51:26 -0400571 while (!runInstance.isDone()) {
572 }
573 StringMap swigmap = (StringMap) runInstance.getVal();
Alexandre Savard713a34d2012-09-26 15:50:41 -0400574
Alexandre Lision2aae48d2013-12-04 13:50:38 -0500575 HashMap<String, String> nativemap = SwigNativeConverter.convertAccountToNative(swigmap);
Alexandre Savard713a34d2012-09-26 15:50:41 -0400576
577 return nativemap;
578 }
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400579
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400580 @SuppressWarnings("unchecked")
581 // Hashmap runtime cast
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400582 @Override
alisioncc7bb422013-06-06 15:31:39 -0400583 public void setAccountDetails(final String accountId, final Map map) {
alision371b77e2013-04-23 14:51:26 -0400584 HashMap<String, String> nativemap = (HashMap<String, String>) map;
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400585
Alexandre Lision2aae48d2013-12-04 13:50:38 -0500586 final StringMap swigmap = SwigNativeConverter.convertFromNativeToSwig(nativemap);
Alexandre Savard718d49f2012-10-02 15:17:13 -0400587
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400588 getExecutor().execute(new SipRunnable() {
589 @Override
590 protected void doRun() throws SameThreadException {
alisioncc7bb422013-06-06 15:31:39 -0400591
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400592 configurationManagerJNI.setAccountDetails(accountId, swigmap);
alisioncc7bb422013-06-06 15:31:39 -0400593 Log.i(TAG, "SipService.setAccountDetails() thread running...");
594 }
595
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400596 });
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400597 }
598
Alexandre Lision451f2a82013-11-12 12:55:55 -0500599 @Override
600 public Map getAccountTemplate() throws RemoteException {
601 class AccountTemplate extends SipRunnableWithReturn {
602
603 @Override
604 protected StringMap doRun() throws SameThreadException {
605 Log.i(TAG, "SipService.getAccountTemplate() thread running...");
606 return configurationManagerJNI.getAccountTemplate();
607 }
608 }
609
610 AccountTemplate runInstance = new AccountTemplate();
611 getExecutor().execute(runInstance);
612
613 while (!runInstance.isDone()) {
614 }
615 StringMap swigmap = (StringMap) runInstance.getVal();
616
Alexandre Lision2aae48d2013-12-04 13:50:38 -0500617 HashMap<String, String> nativemap = SwigNativeConverter.convertAccountToNative(swigmap);
Alexandre Lision451f2a82013-11-12 12:55:55 -0500618
619 return nativemap;
620 }
alisioncc7bb422013-06-06 15:31:39 -0400621
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400622 @SuppressWarnings("unchecked")
623 // Hashmap runtime cast
Alexandre Savard46036572012-10-05 13:56:49 -0400624 @Override
625 public String addAccount(Map map) {
626 class AddAccount extends SipRunnableWithReturn {
627 StringMap map;
alision371b77e2013-04-23 14:51:26 -0400628
629 AddAccount(StringMap m) {
630 map = m;
631 }
632
Alexandre Savard46036572012-10-05 13:56:49 -0400633 @Override
634 protected String doRun() throws SameThreadException {
635 Log.i(TAG, "SipService.getAccountDetails() thread running...");
636 return configurationManagerJNI.addAccount(map);
637 }
alision371b77e2013-04-23 14:51:26 -0400638 }
Alexandre Savard46036572012-10-05 13:56:49 -0400639
Alexandre Lision2aae48d2013-12-04 13:50:38 -0500640 final StringMap swigmap = SwigNativeConverter.convertFromNativeToSwig((HashMap<String, String>) map);
Alexandre Savard46036572012-10-05 13:56:49 -0400641
642 AddAccount runInstance = new AddAccount(swigmap);
643 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400644 while (!runInstance.isDone()) {
645 }
Alexandre Savard46036572012-10-05 13:56:49 -0400646 String accountId = (String) runInstance.getVal();
647
648 return accountId;
649 }
650
651 @Override
652 public void removeAccount(final String accountId) {
653 getExecutor().execute(new SipRunnable() {
654 @Override
655 protected void doRun() throws SameThreadException {
656 Log.i(TAG, "SipService.setAccountDetails() thread running...");
657 configurationManagerJNI.removeAccount(accountId);
658 }
659 });
660 }
alision5f899632013-04-22 17:26:56 -0400661
alision43a9b362013-05-01 16:30:15 -0400662 /*************************
663 * Transfer related API
664 *************************/
665
alision7f18fc82013-05-01 09:37:33 -0400666 @Override
667 public void transfer(final String callID, final String to) throws RemoteException {
668 getExecutor().execute(new SipRunnable() {
669 @Override
670 protected void doRun() throws SameThreadException, RemoteException {
671 Log.i(TAG, "SipService.transfer() thread running...");
672 if (callManagerJNI.transfer(callID, to)) {
673 Bundle bundle = new Bundle();
674 bundle.putString("CallID", callID);
675 bundle.putString("State", "HUNGUP");
676 Intent intent = new Intent(CallManagerCallBack.CALL_STATE_CHANGED);
alision7f18fc82013-05-01 09:37:33 -0400677 intent.putExtra("com.savoirfairelinux.sflphone.service.newstate", bundle);
alision84813a12013-05-27 17:40:39 -0400678 sendBroadcast(intent);
alision7f18fc82013-05-01 09:37:33 -0400679 } else
680 Log.i(TAG, "NOT OK");
681 }
682 });
683
684 }
alision43a9b362013-05-01 16:30:15 -0400685
alision7f18fc82013-05-01 09:37:33 -0400686 @Override
687 public void attendedTransfer(final String transferID, final String targetID) throws RemoteException {
688 getExecutor().execute(new SipRunnable() {
689 @Override
690 protected void doRun() throws SameThreadException, RemoteException {
alision43a9b362013-05-01 16:30:15 -0400691 Log.i(TAG, "SipService.attendedTransfer() thread running...");
alision7f18fc82013-05-01 09:37:33 -0400692 if (callManagerJNI.attendedTransfer(transferID, targetID)) {
693 Log.i(TAG, "OK");
alision7f18fc82013-05-01 09:37:33 -0400694 } else
695 Log.i(TAG, "NOT OK");
696 }
697 });
alision43a9b362013-05-01 16:30:15 -0400698
699 }
700
701 /*************************
702 * Conference related API
703 *************************/
704
705 @Override
706 public void removeConference(final String confID) throws RemoteException {
707 getExecutor().execute(new SipRunnable() {
708 @Override
709 protected void doRun() throws SameThreadException, RemoteException {
710 Log.i(TAG, "SipService.createConference() thread running...");
711 callManagerJNI.removeConference(confID);
712 }
713 });
714
alision7f18fc82013-05-01 09:37:33 -0400715 }
716
717 @Override
alision43a9b362013-05-01 16:30:15 -0400718 public void joinParticipant(final String sel_callID, final String drag_callID) throws RemoteException {
719 getExecutor().execute(new SipRunnable() {
720 @Override
721 protected void doRun() throws SameThreadException, RemoteException {
722 Log.i(TAG, "SipService.joinParticipant() thread running...");
723 callManagerJNI.joinParticipant(sel_callID, drag_callID);
alision806e18e2013-06-21 15:30:17 -0400724 // Generate a CONF_CREATED callback
alision43a9b362013-05-01 16:30:15 -0400725 }
726 });
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500727 Log.i(TAG, "After joining participants");
alision7f18fc82013-05-01 09:37:33 -0400728 }
729
alision7f18fc82013-05-01 09:37:33 -0400730 @Override
alision806e18e2013-06-21 15:30:17 -0400731 public void addParticipant(final SipCall call, final String confID) throws RemoteException {
alision43a9b362013-05-01 16:30:15 -0400732 getExecutor().execute(new SipRunnable() {
733 @Override
734 protected void doRun() throws SameThreadException, RemoteException {
735 Log.i(TAG, "SipService.addParticipant() thread running...");
alision806e18e2013-06-21 15:30:17 -0400736 callManagerJNI.addParticipant(call.getCallId(), confID);
Alexandre Lision945e4612014-01-15 17:40:31 -0500737 mConferences.get(confID).getParticipants().add(call);
alision43a9b362013-05-01 16:30:15 -0400738 }
739 });
740
alision7f18fc82013-05-01 09:37:33 -0400741 }
742
743 @Override
alision43a9b362013-05-01 16:30:15 -0400744 public void addMainParticipant(final String confID) throws RemoteException {
745 getExecutor().execute(new SipRunnable() {
746 @Override
747 protected void doRun() throws SameThreadException, RemoteException {
748 Log.i(TAG, "SipService.addMainParticipant() thread running...");
749 callManagerJNI.addMainParticipant(confID);
750 }
751 });
752
alision7f18fc82013-05-01 09:37:33 -0400753 }
754
755 @Override
alision43a9b362013-05-01 16:30:15 -0400756 public void detachParticipant(final String callID) throws RemoteException {
757 getExecutor().execute(new SipRunnable() {
758 @Override
759 protected void doRun() throws SameThreadException, RemoteException {
760 Log.i(TAG, "SipService.detachParticipant() thread running...");
alision806e18e2013-06-21 15:30:17 -0400761 Log.i(TAG, "Detaching " + callID);
Alexandre Lision945e4612014-01-15 17:40:31 -0500762 Iterator<Entry<String, Conference>> it = mConferences.entrySet().iterator();
763 Log.i(TAG, "mConferences size " + mConferences.size());
alision806e18e2013-06-21 15:30:17 -0400764 while (it.hasNext()) {
765 Conference tmp = it.next().getValue();
766 Log.i(TAG, "conf has " + tmp.getParticipants().size() + " participants");
767 if (tmp.contains(callID)) {
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500768 Conference toDetach = new Conference(tmp.getCallById(callID));
Alexandre Lision945e4612014-01-15 17:40:31 -0500769 mConferences.put(toDetach.getId(), toDetach);
alision806e18e2013-06-21 15:30:17 -0400770 Log.i(TAG, "Call found and put in current_calls");
771 }
772 }
alision43a9b362013-05-01 16:30:15 -0400773 callManagerJNI.detachParticipant(callID);
774 }
775 });
776
alision7f18fc82013-05-01 09:37:33 -0400777 }
778
779 @Override
alision43a9b362013-05-01 16:30:15 -0400780 public void joinConference(final String sel_confID, final String drag_confID) throws RemoteException {
781 getExecutor().execute(new SipRunnable() {
782 @Override
783 protected void doRun() throws SameThreadException, RemoteException {
784 Log.i(TAG, "SipService.joinConference() thread running...");
785 callManagerJNI.joinConference(sel_confID, drag_confID);
786 }
787 });
788
alision7f18fc82013-05-01 09:37:33 -0400789 }
790
791 @Override
alision43a9b362013-05-01 16:30:15 -0400792 public void hangUpConference(final String confID) throws RemoteException {
793 getExecutor().execute(new SipRunnable() {
794 @Override
795 protected void doRun() throws SameThreadException, RemoteException {
796 Log.i(TAG, "SipService.joinConference() thread running...");
797 callManagerJNI.hangUpConference(confID);
798 }
799 });
800
alision7f18fc82013-05-01 09:37:33 -0400801 }
802
803 @Override
alision43a9b362013-05-01 16:30:15 -0400804 public void holdConference(final String confID) throws RemoteException {
805 getExecutor().execute(new SipRunnable() {
806 @Override
807 protected void doRun() throws SameThreadException, RemoteException {
808 Log.i(TAG, "SipService.holdConference() thread running...");
809 callManagerJNI.holdConference(confID);
810 }
811 });
812
alision7f18fc82013-05-01 09:37:33 -0400813 }
814
815 @Override
alision43a9b362013-05-01 16:30:15 -0400816 public void unholdConference(final String confID) throws RemoteException {
817 getExecutor().execute(new SipRunnable() {
818 @Override
819 protected void doRun() throws SameThreadException, RemoteException {
820 Log.i(TAG, "SipService.unholdConference() thread running...");
821 callManagerJNI.unholdConference(confID);
822 }
823 });
824
alision7f18fc82013-05-01 09:37:33 -0400825 }
Alexandre Lision67817192013-07-18 12:04:30 -0400826
alisioncd8fb912013-06-28 14:43:51 -0400827 @Override
828 public boolean isConferenceParticipant(final String callID) throws RemoteException {
829 class IsParticipant extends SipRunnableWithReturn {
830
831 @Override
832 protected Boolean doRun() throws SameThreadException {
833 Log.i(TAG, "SipService.isRecording() thread running...");
834 return callManagerJNI.isConferenceParticipant(callID);
835 }
836 }
837
838 IsParticipant runInstance = new IsParticipant();
839 getExecutor().execute(runInstance);
840 while (!runInstance.isDone()) {
841 }
842
843 return (Boolean) runInstance.getVal();
844 }
alision7f18fc82013-05-01 09:37:33 -0400845
846 @Override
alisiondf1dac92013-06-27 17:35:53 -0400847 public HashMap<String, Conference> getConferenceList() throws RemoteException {
Alexandre Lision67817192013-07-18 12:04:30 -0400848 // class ConfList extends SipRunnableWithReturn {
849 // @Override
850 // protected StringVect doRun() throws SameThreadException {
851 // Log.i(TAG, "SipService.getConferenceList() thread running...");
852 // return callManagerJNI.getConferenceList();
853 // }
854 // }
855 // ;
856 // ConfList runInstance = new ConfList();
857 // getExecutor().execute(runInstance);
858 // while (!runInstance.isDone()) {
859 // // Log.w(TAG, "Waiting for getConferenceList");
860 // }
861 // StringVect swigvect = (StringVect) runInstance.getVal();
862 //
863 // ArrayList<String> nativelist = new ArrayList<String>();
864 //
865 // for (int i = 0; i < swigvect.size(); i++)
866 // nativelist.add(swigvect.get(i));
867 //
868 // return nativelist;
Alexandre Lision945e4612014-01-15 17:40:31 -0500869 return mConferences;
alision7f18fc82013-05-01 09:37:33 -0400870 }
871
872 @Override
alision907bde72013-06-20 14:40:37 -0400873 public List getParticipantList(final String confID) throws RemoteException {
874 class PartList extends SipRunnableWithReturn {
875 @Override
876 protected StringVect doRun() throws SameThreadException {
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500877 Log.i(TAG, "SipService.getParticipantList() thread running...");
alision907bde72013-06-20 14:40:37 -0400878 return callManagerJNI.getParticipantList(confID);
879 }
880 }
881 ;
882 PartList runInstance = new PartList();
883 getExecutor().execute(runInstance);
884 while (!runInstance.isDone()) {
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500885 Log.w(TAG, "getParticipantList");
alision907bde72013-06-20 14:40:37 -0400886 }
887 StringVect swigvect = (StringVect) runInstance.getVal();
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500888 Log.w(TAG, "After that");
alision907bde72013-06-20 14:40:37 -0400889 ArrayList<String> nativelist = new ArrayList<String>();
890
891 for (int i = 0; i < swigvect.size(); i++)
892 nativelist.add(swigvect.get(i));
893
894 return nativelist;
alision7f18fc82013-05-01 09:37:33 -0400895 }
alision806e18e2013-06-21 15:30:17 -0400896
alision1005ba12013-06-19 13:52:44 -0400897 @Override
alision7f18fc82013-05-01 09:37:33 -0400898 public String getConferenceId(String callID) throws RemoteException {
alision43a9b362013-05-01 16:30:15 -0400899 Log.e(TAG, "getConferenceList not implemented");
alision7f18fc82013-05-01 09:37:33 -0400900 return null;
901 }
902
903 @Override
alision806e18e2013-06-21 15:30:17 -0400904 public String getConferenceDetails(final String callID) throws RemoteException {
905 class ConfDetails extends SipRunnableWithReturn {
906 @Override
907 protected StringMap doRun() throws SameThreadException {
908 Log.i(TAG, "SipService.getAccountList() thread running...");
909 return callManagerJNI.getConferenceDetails(callID);
910 }
911 }
912 ;
913 ConfDetails runInstance = new ConfDetails();
914 getExecutor().execute(runInstance);
915 while (!runInstance.isDone()) {
916 // Log.w(TAG, "Waiting for getConferenceList");
917 }
918 StringMap swigvect = (StringMap) runInstance.getVal();
919
920 return swigvect.get("CONF_STATE");
alision7f18fc82013-05-01 09:37:33 -0400921 }
922
alision04a00182013-05-10 17:05:29 -0400923 @Override
924 public String getRecordPath() throws RemoteException {
925 class RecordPath extends SipRunnableWithReturn {
926
927 @Override
928 protected String doRun() throws SameThreadException {
929 Log.i(TAG, "SipService.getRecordPath() thread running...");
Adrien Béraud9360f242013-09-19 11:07:42 +1000930 return configurationManagerJNI.getRecordPath();
alision04a00182013-05-10 17:05:29 -0400931 }
932 }
933
934 RecordPath runInstance = new RecordPath();
935 getExecutor().execute(runInstance);
936 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400937 // Log.w(TAG, "Waiting for getRecordPath");
alision04a00182013-05-10 17:05:29 -0400938 }
939 String path = (String) runInstance.getVal();
940
941 return path;
942 }
943
944 @Override
Alexandre Lisiona764c682013-09-09 10:02:07 -0400945 public boolean toggleRecordingCall(final String id) throws RemoteException {
Adrien Béraud9360f242013-09-19 11:07:42 +1000946
Alexandre Lisiona764c682013-09-09 10:02:07 -0400947 class ToggleRecording extends SipRunnableWithReturn {
948
alision04a00182013-05-10 17:05:29 -0400949 @Override
Alexandre Lisiona764c682013-09-09 10:02:07 -0400950 protected Boolean doRun() throws SameThreadException {
951 Log.i(TAG, "SipService.toggleRecordingCall() thread running...");
Alexandre Lision3874e552013-11-04 17:20:12 -0500952 boolean result = callManagerJNI.toggleRecording(id);
Alexandre Lision35577132013-12-06 15:21:15 -0500953
Alexandre Lision945e4612014-01-15 17:40:31 -0500954 if (getConferences().containsKey(id)) {
955 getConferences().get(id).setRecording(result);
Alexandre Lision3874e552013-11-04 17:20:12 -0500956 } else {
Alexandre Lision945e4612014-01-15 17:40:31 -0500957 Iterator<Conference> it = getConferences().values().iterator();
Alexandre Lision3874e552013-11-04 17:20:12 -0500958 while (it.hasNext()) {
959 Conference c = it.next();
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -0500960 if (c.getCallById(id) != null)
961 c.getCallById(id).setRecording(result);
Alexandre Lision3874e552013-11-04 17:20:12 -0500962 }
963 }
964 return result;
alision04a00182013-05-10 17:05:29 -0400965 }
Alexandre Lisiona764c682013-09-09 10:02:07 -0400966 }
967
968 ToggleRecording runInstance = new ToggleRecording();
969 getExecutor().execute(runInstance);
970 while (!runInstance.isDone()) {
971 }
972
973 return (Boolean) runInstance.getVal();
alision04a00182013-05-10 17:05:29 -0400974
975 }
Alexandre Lision67817192013-07-18 12:04:30 -0400976
alision50fa0722013-06-25 17:29:44 -0400977 @Override
978 public boolean startRecordedFilePlayback(final String filepath) throws RemoteException {
979 getExecutor().execute(new SipRunnable() {
980 @Override
981 protected void doRun() throws SameThreadException, RemoteException {
982 Log.i(TAG, "SipService.setRecordingCall() thread running...");
983 callManagerJNI.startRecordedFilePlayback(filepath);
984 }
985 });
986 return false;
987 }
988
989 @Override
990 public void stopRecordedFilePlayback(final String filepath) throws RemoteException {
991 getExecutor().execute(new SipRunnable() {
992 @Override
993 protected void doRun() throws SameThreadException, RemoteException {
994 Log.i(TAG, "SipService.stopRecordedFilePlayback() thread running...");
995 callManagerJNI.stopRecordedFilePlayback(filepath);
996 }
997 });
998 }
alision04a00182013-05-10 17:05:29 -0400999
1000 @Override
1001 public void setRecordPath(final String path) throws RemoteException {
1002 getExecutor().execute(new SipRunnable() {
1003 @Override
1004 protected void doRun() throws SameThreadException, RemoteException {
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001005 Log.i(TAG, "SipService.setRecordPath() " + path + " thread running...");
Adrien Béraud9360f242013-09-19 11:07:42 +10001006 configurationManagerJNI.setRecordPath(path);
alision04a00182013-05-10 17:05:29 -04001007 }
1008 });
1009 }
1010
1011 @Override
Alexandre Lisiond5686032013-10-29 11:09:21 -04001012 public void sendTextMessage(final String callID, final SipMessage message) throws RemoteException {
alision04a00182013-05-10 17:05:29 -04001013 getExecutor().execute(new SipRunnable() {
1014 @Override
1015 protected void doRun() throws SameThreadException, RemoteException {
1016 Log.i(TAG, "SipService.sendTextMessage() thread running...");
Alexandre Lisiond5686032013-10-29 11:09:21 -04001017 callManagerJNI.sendTextMessage(callID, message.comment);
Alexandre Lision945e4612014-01-15 17:40:31 -05001018 if (getConferences().get(callID) != null)
1019 getConferences().get(callID).addSipMessage(message);
alision04a00182013-05-10 17:05:29 -04001020 }
1021 });
1022
1023 }
1024
alisiond295ec22013-05-17 10:12:13 -04001025 @Override
Alexandre Lision4cf78702013-10-16 13:43:23 -04001026 public List getAudioCodecList(final String accountID) throws RemoteException {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001027 class AudioCodecList extends SipRunnableWithReturn {
1028
1029 @Override
Alexandre Lision933ef0a2013-10-15 17:28:40 -04001030 protected ArrayList<Codec> doRun() throws SameThreadException {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001031 Log.i(TAG, "SipService.getAudioCodecList() thread running...");
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001032 ArrayList<Codec> results = new ArrayList<Codec>();
Alexandre Lision4cf78702013-10-16 13:43:23 -04001033
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001034 IntVect active_payloads = configurationManagerJNI.getActiveAudioCodecList(accountID);
1035 for (int i = 0; i < active_payloads.size(); ++i) {
1036
Alexandre Lision039a3cf2013-10-16 17:44:57 -04001037 results.add(new Codec(active_payloads.get(i), configurationManagerJNI.getAudioCodecDetails(active_payloads.get(i)), true));
Alexandre Lisione0045442013-10-25 09:16:19 -04001038
Alexandre Lision4cf78702013-10-16 13:43:23 -04001039 }
Alexandre Lision039a3cf2013-10-16 17:44:57 -04001040 IntVect payloads = configurationManagerJNI.getAudioCodecList();
1041
1042 for (int i = 0; i < payloads.size(); ++i) {
1043 boolean isActive = false;
1044 for (Codec co : results) {
1045 if (co.getPayload().toString().contentEquals(String.valueOf(payloads.get(i))))
1046 isActive = true;
1047
1048 }
1049 if (isActive)
1050 continue;
1051 else
1052 results.add(new Codec(payloads.get(i), configurationManagerJNI.getAudioCodecDetails(payloads.get(i)), false));
1053
1054 }
1055
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001056 return results;
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001057 }
1058 }
1059
1060 AudioCodecList runInstance = new AudioCodecList();
1061 getExecutor().execute(runInstance);
1062 while (!runInstance.isDone()) {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001063 }
Alexandre Lision933ef0a2013-10-15 17:28:40 -04001064 ArrayList<Codec> codecs = (ArrayList<Codec>) runInstance.getVal();
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001065 return codecs;
alisiond295ec22013-05-17 10:12:13 -04001066 }
1067
alision9f7a6ec2013-05-24 16:26:26 -04001068 @Override
Alexandre Lision4cf78702013-10-16 13:43:23 -04001069 public Map getRingtoneList() throws RemoteException {
1070 class RingtoneList extends SipRunnableWithReturn {
1071
1072 @Override
1073 protected StringMap doRun() throws SameThreadException {
1074 Log.i(TAG, "SipService.getRingtoneList() thread running...");
1075 return configurationManagerJNI.getRingtoneList();
1076 }
1077 }
1078
1079 RingtoneList runInstance = new RingtoneList();
1080 getExecutor().execute(runInstance);
1081 while (!runInstance.isDone()) {
1082 }
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001083 StringMap ringtones = (StringMap) runInstance.getVal();
1084
1085 for (int i = 0; i < ringtones.size(); ++i) {
1086 // Log.i(TAG,"ringtones "+i+" "+ ringtones.);
1087 }
1088
Alexandre Lision4cf78702013-10-16 13:43:23 -04001089 return null;
1090 }
1091
1092 @Override
1093 public void setActiveCodecList(final List codecs, final String accountID) throws RemoteException {
1094 getExecutor().execute(new SipRunnable() {
1095 @Override
1096 protected void doRun() throws SameThreadException, RemoteException {
1097 Log.i(TAG, "SipService.setActiveAudioCodecList() thread running...");
1098 StringVect list = new StringVect();
1099 for (int i = 0; i < codecs.size(); ++i) {
1100 list.add((String) codecs.get(i));
1101 }
1102 configurationManagerJNI.setActiveAudioCodecList(list, accountID);
1103 }
1104 });
1105 }
1106
alision2cb99562013-05-30 17:02:20 -04001107 /***********************
1108 * Notification API
1109 ***********************/
1110 @Override
1111 public void createNotification() throws RemoteException {
alisioncc7bb422013-06-06 15:31:39 -04001112
alision2cb99562013-05-30 17:02:20 -04001113 }
1114
1115 @Override
1116 public void destroyNotification() throws RemoteException {
alisioncc7bb422013-06-06 15:31:39 -04001117
alision2cb99562013-05-30 17:02:20 -04001118 }
alisioncc7bb422013-06-06 15:31:39 -04001119
alisiondf1dac92013-06-27 17:35:53 -04001120 @Override
1121 public Conference getCurrentCall() throws RemoteException {
Alexandre Lision945e4612014-01-15 17:40:31 -05001122 for (Conference conf : mConferences.values()) {
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -05001123 if (conf.isIncoming())
1124 return conf;
alisiondf1dac92013-06-27 17:35:53 -04001125 }
Alexandre Lision67817192013-07-18 12:04:30 -04001126
Alexandre Lision945e4612014-01-15 17:40:31 -05001127 for (Conference conf : mConferences.values()) {
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -05001128 if (conf.isOnGoing())
1129 return conf;
alisiondf1dac92013-06-27 17:35:53 -04001130 }
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -05001131
alisiondf1dac92013-06-27 17:35:53 -04001132 return null;
1133 }
1134
Alexandre Lision64dc8c02013-09-25 15:32:25 -04001135 @Override
1136 public void playDtmf(final String key) throws RemoteException {
1137 getExecutor().execute(new SipRunnable() {
1138 @Override
1139 protected void doRun() throws SameThreadException, RemoteException {
1140 Log.i(TAG, "SipService.playDtmf() thread running...");
1141 callManagerJNI.playDTMF(key);
1142 }
1143 });
1144 }
1145
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001146 @Override
1147 public List getConcurrentCalls() throws RemoteException {
Alexandre Lision945e4612014-01-15 17:40:31 -05001148 return new ArrayList(mConferences.values());
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -05001149 }
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001150
Alexandre Lisiona9ee4eb2014-01-15 16:20:35 -05001151 @Override
1152 public Conference getConference(String id) throws RemoteException {
Alexandre Lision945e4612014-01-15 17:40:31 -05001153 return mConferences.get(id);
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001154 }
1155
Alexandre Lision4fb22622013-10-21 16:26:33 -04001156 @Override
1157 public String getCurrentAudioCodecName(String callID) throws RemoteException {
1158 return callManagerJNI.getCurrentAudioCodecName(callID);
1159 }
1160
Alexandre Lision31e30902013-11-08 15:16:59 -05001161 @Override
1162 public void setMuted(final boolean mute) throws RemoteException {
1163 getExecutor().execute(new SipRunnable() {
1164 @Override
1165 protected void doRun() throws SameThreadException, RemoteException {
1166 Log.i(TAG, "SipService.setMuted() thread running...");
1167 configurationManagerJNI.muteCapture(mute);
1168 }
1169 });
1170 }
1171
1172 @Override
1173 public boolean isCaptureMuted() throws RemoteException {
1174 class IsMuted extends SipRunnableWithReturn {
1175
1176 @Override
1177 protected Boolean doRun() throws SameThreadException {
1178 Log.i(TAG, "SipService.isCaptureMuted() thread running...");
1179 return configurationManagerJNI.isCaptureMuted();
1180 }
1181 }
1182
1183 IsMuted runInstance = new IsMuted();
1184 getExecutor().execute(runInstance);
1185 while (!runInstance.isDone()) {
1186 }
1187
1188 return (Boolean) runInstance.getVal();
1189 }
1190
Alexandre Lision3b7148e2013-11-13 17:23:06 -05001191 @Override
Alexandre Lision48b49eb2014-02-11 13:37:33 -05001192 public void confirmSAS(final String callID) throws RemoteException {
1193 getExecutor().execute(new SipRunnable() {
1194 @Override
1195 protected void doRun() throws SameThreadException, RemoteException {
1196 Log.i(TAG, "SipService.confirmSAS() thread running...");
Alexandre Lision1b932d82014-02-21 10:03:19 -05001197 SecureSipCall call = (SecureSipCall) getCallById(callID);
1198 call.setConfirmedSAS(true);
Alexandre Lision48b49eb2014-02-11 13:37:33 -05001199 callManagerJNI.setSASVerified(callID);
1200 }
1201 });
1202 }
1203
1204 @Override
Alexandre Lision3b7148e2013-11-13 17:23:06 -05001205 public List getCredentials(final String accountID) throws RemoteException {
1206 class Credentials extends SipRunnableWithReturn {
1207
1208 @Override
1209 protected List doRun() throws SameThreadException {
1210 Log.i(TAG, "SipService.getCredentials() thread running...");
1211 VectMap map = configurationManagerJNI.getCredentials(accountID);
Alexandre Lision2aae48d2013-12-04 13:50:38 -05001212 ArrayList<HashMap<String, String>> result = SwigNativeConverter.convertCredentialsToNative(map);
Alexandre Lision3b7148e2013-11-13 17:23:06 -05001213 return result;
1214 }
1215 }
1216
1217 Credentials runInstance = new Credentials();
1218 getExecutor().execute(runInstance);
1219 while (!runInstance.isDone()) {
1220 }
1221 return (List) runInstance.getVal();
1222 }
1223
1224 @Override
1225 public void setCredentials(final String accountID, final List creds) throws RemoteException {
1226 getExecutor().execute(new SipRunnable() {
1227 @Override
1228 protected void doRun() throws SameThreadException, RemoteException {
1229 Log.i(TAG, "SipService.setCredentials() thread running...");
Alexandre Lision3cefec22013-11-14 17:26:35 -05001230 ArrayList<HashMap<String, String>> list = (ArrayList<HashMap<String, String>>) creds;
Alexandre Lision2aae48d2013-12-04 13:50:38 -05001231 configurationManagerJNI.setCredentials(accountID, SwigNativeConverter.convertFromNativeToSwig(creds));
Alexandre Lision3b7148e2013-11-13 17:23:06 -05001232 }
1233 });
1234 }
1235
Alexandre Lision3e2a1d02013-11-19 17:23:00 -05001236 @Override
1237 public void registerAllAccounts() throws RemoteException {
1238 getExecutor().execute(new SipRunnable() {
1239 @Override
1240 protected void doRun() throws SameThreadException, RemoteException {
1241 Log.i(TAG, "SipService.registerAllAccounts() thread running...");
1242 configurationManagerJNI.registerAllAccounts();
1243 }
1244 });
1245 }
1246
Alexandre Lision5f733bc2013-12-04 13:10:30 -05001247 @Override
Alexandre Lision35577132013-12-06 15:21:15 -05001248 public void toggleSpeakerPhone(boolean toggle) throws RemoteException {
1249 if (toggle)
Alexandre Lision945e4612014-01-15 17:40:31 -05001250 mMediaManager.RouteToSpeaker();
Alexandre Lision35577132013-12-06 15:21:15 -05001251 else
Alexandre Lision945e4612014-01-15 17:40:31 -05001252 mMediaManager.RouteToInternalSpeaker();
Alexandre Lision5f733bc2013-12-04 13:10:30 -05001253 }
1254
Emeric Vigier6119d782012-09-21 18:04:14 -04001255 };
Alexandre Lision3c37dca2014-02-21 14:13:26 -05001256
1257 private void removeCall(String callID) {
1258 Conference conf = findConference(callID);
1259 if(conf == null)
1260 return;
1261 if(conf.getParticipants().size() == 1)
1262 getConferences().remove(conf.getId());
1263 else
1264 conf.removeParticipant(conf.getCallById(callID));
1265 }
1266
1267 protected Conference findConference(String callID) {
1268 Conference result = null;
1269 if (getConferences().get(callID) != null) {
1270 result = getConferences().get(callID);
1271 } else {
1272 Iterator<Map.Entry<String, Conference>> it = getConferences().entrySet().iterator();
1273 while (it.hasNext()) {
1274 Conference tmp = it.next().getValue();
1275 for (SipCall c : tmp.getParticipants()) {
1276 if (c.getCallId().contentEquals(callID)) {
1277 result = tmp;
1278 }
1279 }
1280 }
1281 }
1282 return result;
1283 }
Alexandre Lision35577132013-12-06 15:21:15 -05001284}