blob: 848070854d075833e38bb84d295c3c4a5b442236 [file] [log] [blame]
Emeric Vigier6119d782012-09-21 18:04:14 -04001/**
2 * Copyright (C) 2010-2012 Regis Montoya (aka r3gis - www.r3gis.fr)
alisionb1763882013-06-18 17:30:51 -04003 * Copyright (C) 2004-2013 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
Emeric Vigier6119d782012-09-21 18:04:14 -040027import java.lang.ref.WeakReference;
alision17052d42013-04-22 10:39:38 -040028import java.util.ArrayList;
29import java.util.HashMap;
alisioncc7bb422013-06-06 15:31:39 -040030import java.util.Iterator;
alision7f18fc82013-05-01 09:37:33 -040031import java.util.List;
alision17052d42013-04-22 10:39:38 -040032import java.util.Map;
alision806e18e2013-06-21 15:30:17 -040033import java.util.Map.Entry;
alision2cb99562013-05-30 17:02:20 -040034import java.util.Random;
Emeric Vigier6119d782012-09-21 18:04:14 -040035
Alexandre Lision3ccccf02013-10-07 14:10:46 -040036import org.sflphone.R;
Alexandre Lision064e1e02013-10-01 16:18:42 -040037import org.sflphone.account.AccountDetailBasic;
38import org.sflphone.account.AccountDetailsHandler;
39import org.sflphone.account.CallDetailsHandler;
40import org.sflphone.account.HistoryHandler;
41import org.sflphone.client.SFLPhoneHomeActivity;
Alexandre Lision933ef0a2013-10-15 17:28:40 -040042import org.sflphone.model.Codec;
Alexandre Lision064e1e02013-10-01 16:18:42 -040043import org.sflphone.model.Conference;
44import org.sflphone.model.SipCall;
45import org.sflphone.receivers.IncomingReceiver;
46
alision2cb99562013-05-30 17:02:20 -040047import android.app.Notification;
48import android.app.NotificationManager;
49import android.app.PendingIntent;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040050import android.app.Service;
alision17052d42013-04-22 10:39:38 -040051import android.content.Context;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040052import android.content.Intent;
alision17052d42013-04-22 10:39:38 -040053import android.content.IntentFilter;
alision7f18fc82013-05-01 09:37:33 -040054import android.os.Bundle;
Emeric Vigier6119d782012-09-21 18:04:14 -040055import android.os.Handler;
56import android.os.HandlerThread;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040057import android.os.IBinder;
Emeric Vigier6119d782012-09-21 18:04:14 -040058import android.os.Looper;
59import android.os.Message;
alision5f899632013-04-22 17:26:56 -040060import android.os.RemoteException;
alision2cb99562013-05-30 17:02:20 -040061import android.support.v4.app.NotificationCompat;
alision17052d42013-04-22 10:39:38 -040062import android.support.v4.content.LocalBroadcastManager;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040063import android.util.Log;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040064
Emeric Vigiereaf2c492012-09-19 14:38:20 -040065public class SipService extends Service {
66
67 static final String TAG = "SipService";
68 static final int DELAY = 5000; /* 5 sec */
69 private boolean runFlag = false;
70 private SipServiceThread sipServiceThread;
Emeric Vigier6119d782012-09-21 18:04:14 -040071 private SipServiceExecutor mExecutor;
72 private static HandlerThread executorThread;
alision3ea8f3c2013-07-16 17:35:35 -040073 private CallManager callManagerJNI;
Alexandre Lision67817192013-07-18 12:04:30 -040074 private ManagerImpl managerImpl;
Emeric Vigier0007dee2012-09-24 11:35:58 -040075 private CallManagerCallBack callManagerCallBack;
alision3ea8f3c2013-07-16 17:35:35 -040076 private ConfigurationManager configurationManagerJNI;
Alexandre Savardfccd1dc2012-10-17 17:31:38 -040077 private ConfigurationManagerCallback configurationManagerCallback;
Emeric Vigier6119d782012-09-21 18:04:14 -040078 private boolean isPjSipStackStarted = false;
alisioncc7bb422013-06-06 15:31:39 -040079
alision2cb99562013-05-30 17:02:20 -040080 public static final String NOTIF_CREATION = "notif_creation";
81 public static final String NOTIF_DELETION = "notif_deletion";
alision04a00182013-05-10 17:05:29 -040082
alision2cb99562013-05-30 17:02:20 -040083 private HashMap<String, SipCall> current_calls = new HashMap<String, SipCall>();
alision806e18e2013-06-21 15:30:17 -040084 private HashMap<String, Conference> current_confs = new HashMap<String, Conference>();
85 private IncomingReceiver receiver;
Emeric Vigier6119d782012-09-21 18:04:14 -040086
alision806e18e2013-06-21 15:30:17 -040087 public HashMap<String, Conference> getCurrent_confs() {
88 return current_confs;
89 }
alision43a9b362013-05-01 16:30:15 -040090
91 @Override
92 public boolean onUnbind(Intent i) {
93 super.onUnbind(i);
94 Log.i(TAG, "onUnbind(intent)");
95 return false;
96
97 }
98
99 /* called once by startService() */
100 @Override
101 public void onCreate() {
102 Log.i(TAG, "onCreated");
103 super.onCreate();
104
alision43a9b362013-05-01 16:30:15 -0400105 sipServiceThread = new SipServiceThread();
106
107 IntentFilter callFilter = new IntentFilter(CallManagerCallBack.CALL_STATE_CHANGED);
108 callFilter.addAction(CallManagerCallBack.INCOMING_CALL);
109 callFilter.addAction(CallManagerCallBack.NEW_CALL_CREATED);
alision4a0eb092013-05-07 13:52:03 -0400110 callFilter.addAction(ConfigurationManagerCallback.ACCOUNT_STATE_CHANGED);
111 callFilter.addAction(ConfigurationManagerCallback.ACCOUNTS_CHANGED);
alision04a00182013-05-10 17:05:29 -0400112 callFilter.addAction(CallManagerCallBack.INCOMING_TEXT);
alision806e18e2013-06-21 15:30:17 -0400113 callFilter.addAction(CallManagerCallBack.CONF_CREATED);
114 callFilter.addAction(CallManagerCallBack.CONF_REMOVED);
115 callFilter.addAction(CallManagerCallBack.CONF_CHANGED);
alisiondf1dac92013-06-27 17:35:53 -0400116 callFilter.addAction(CallManagerCallBack.RECORD_STATE_CHANGED);
alision806e18e2013-06-21 15:30:17 -0400117 receiver = new IncomingReceiver(this, mBinder);
alision2cb99562013-05-30 17:02:20 -0400118 LocalBroadcastManager.getInstance(this).registerReceiver(receiver, callFilter);
alision2cb99562013-05-30 17:02:20 -0400119
alisioncc7bb422013-06-06 15:31:39 -0400120 getExecutor().execute(new StartRunnable());
alisioncc7bb422013-06-06 15:31:39 -0400121 }
alision43a9b362013-05-01 16:30:15 -0400122
123 /* called for each startService() */
124 @Override
125 public int onStartCommand(Intent intent, int flags, int startId) {
126 Log.i(TAG, "onStarted");
127 super.onStartCommand(intent, flags, startId);
128
alision806e18e2013-06-21 15:30:17 -0400129 receiver = new IncomingReceiver(this, mBinder);
alision43a9b362013-05-01 16:30:15 -0400130 if (!runFlag) {
131 sipServiceThread.start();
132 runFlag = true;
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400133 // sflphoneApp.setServiceRunning(true);
Alexandre Lision0a300ff2013-09-23 14:22:34 -0400134 Log.i(TAG, "Sflphone Service started");
alision43a9b362013-05-01 16:30:15 -0400135 }
136
alision907bde72013-06-20 14:40:37 -0400137 return START_NOT_STICKY; /* started and stopped explicitly */
alision43a9b362013-05-01 16:30:15 -0400138 }
139
140 @Override
141 public void onDestroy() {
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400142 Log.i(TAG, "onDestroyed");
alision43a9b362013-05-01 16:30:15 -0400143 /* called once by stopService() */
144 sipServiceThread.interrupt();
145 sipServiceThread = null;
146 runFlag = false;
Alexandre Lision0a300ff2013-09-23 14:22:34 -0400147
148 LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
alision2cb99562013-05-30 17:02:20 -0400149
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400150 // sflphoneApp.setServiceRunning(false);
151 // Toast.makeText(this, "Sflphone Service stopped", Toast.LENGTH_SHORT).show();
alision43a9b362013-05-01 16:30:15 -0400152 super.onDestroy();
153
alision43a9b362013-05-01 16:30:15 -0400154 }
155
156 @Override
157 public IBinder onBind(Intent arg0) {
158 Log.i(TAG, "onBound");
159 return mBinder;
160 }
161
162 private static Looper createLooper() {
163 if (executorThread == null) {
164 Log.d(TAG, "Creating new handler thread");
165 // ADT gives a fake warning due to bad parse rule.
166 executorThread = new HandlerThread("SipService.Executor");
167 executorThread.start();
168 }
169 return executorThread.getLooper();
170 }
171
172 public SipServiceExecutor getExecutor() {
173 // create mExecutor lazily
174 if (mExecutor == null) {
175 mExecutor = new SipServiceExecutor(this);
176 }
177 return mExecutor;
178 }
179
180 // Executes immediate tasks in a single executorThread.
181 public static class SipServiceExecutor extends Handler {
182 WeakReference<SipService> handlerService;
183
184 SipServiceExecutor(SipService s) {
185 super(createLooper());
186 handlerService = new WeakReference<SipService>(s);
187 }
188
189 public void execute(Runnable task) {
190 // TODO: add wakelock
191 Message.obtain(this, 0/* don't care */, task).sendToTarget();
Alexandre Lisioncdec5952013-07-17 14:18:22 -0400192 Log.w(TAG, "SenT!");
alision43a9b362013-05-01 16:30:15 -0400193 }
194
195 @Override
196 public void handleMessage(Message msg) {
197 if (msg.obj instanceof Runnable) {
198 executeInternal((Runnable) msg.obj);
199 } else {
200 Log.w(TAG, "can't handle msg: " + msg);
201 }
202 }
203
204 private void executeInternal(Runnable task) {
205 try {
206 task.run();
207 } catch (Throwable t) {
208 Log.e(TAG, "run task: " + task, t);
209 }
210 }
211 }
212
213 private void startPjSipStack() throws SameThreadException {
214 if (isPjSipStackStarted)
215 return;
216
217 try {
218 System.loadLibrary("gnustl_shared");
219 System.loadLibrary("expat");
220 System.loadLibrary("yaml");
221 System.loadLibrary("ccgnu2");
222 System.loadLibrary("crypto");
223 System.loadLibrary("ssl");
Alexandre Lision7c6f4a62013-09-05 13:27:01 -0400224 System.loadLibrary("sndfile");
alision43a9b362013-05-01 16:30:15 -0400225 System.loadLibrary("ccrtp1");
alision43a9b362013-05-01 16:30:15 -0400226 System.loadLibrary("samplerate");
227 System.loadLibrary("codec_ulaw");
228 System.loadLibrary("codec_alaw");
Alexandre Lision0a300ff2013-09-23 14:22:34 -0400229 System.loadLibrary("codec_g722");
Alexandre Lision6deda412013-09-25 13:21:22 -0400230 System.loadLibrary("codec_opus");
Alexandre Lisiona1ad1c32013-10-15 16:35:20 -0400231 System.loadLibrary("codec_gsm");
alision43a9b362013-05-01 16:30:15 -0400232 System.loadLibrary("speexresampler");
233 System.loadLibrary("sflphone");
234 isPjSipStackStarted = true;
Adrien Béraud9360f242013-09-19 11:07:42 +1000235
alision43a9b362013-05-01 16:30:15 -0400236 } catch (UnsatisfiedLinkError e) {
237 Log.e(TAG, "Problem with the current Pj stack...", e);
238 isPjSipStackStarted = false;
239 return;
240 } catch (Exception e) {
241 Log.e(TAG, "Problem with the current Pj stack...", e);
242 }
243
Alexandre Lision67817192013-07-18 12:04:30 -0400244 Log.i(TAG, "PjSIPStack started");
245 managerImpl = SFLPhoneservice.instance();
246
247 /* set static AppPath before calling manager.init */
248
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400249 // managerImpl.setPath(sflphoneApp.getAppPath());
alision43a9b362013-05-01 16:30:15 -0400250
alision3ea8f3c2013-07-16 17:35:35 -0400251 callManagerJNI = new CallManager();
alision43a9b362013-05-01 16:30:15 -0400252 callManagerCallBack = new CallManagerCallBack(this);
253 SFLPhoneservice.setCallbackObject(callManagerCallBack);
254
alision3ea8f3c2013-07-16 17:35:35 -0400255 configurationManagerJNI = new ConfigurationManager();
alision43a9b362013-05-01 16:30:15 -0400256 configurationManagerCallback = new ConfigurationManagerCallback(this);
257 SFLPhoneservice.setConfigurationCallbackObject(configurationManagerCallback);
Adrien Béraud9360f242013-09-19 11:07:42 +1000258
Alexandre Lision67817192013-07-18 12:04:30 -0400259 Log.i(TAG, "before init");
260 managerImpl.init("");
Adrien Béraud9360f242013-09-19 11:07:42 +1000261
Alexandre Lision67817192013-07-18 12:04:30 -0400262 Log.i(TAG, "->startPjSipStack");
alision43a9b362013-05-01 16:30:15 -0400263
alision43a9b362013-05-01 16:30:15 -0400264 }
265
Adrien Béraud9360f242013-09-19 11:07:42 +1000266 public HashMap<String, SipCall> getCurrent_calls() {
alision2cb99562013-05-30 17:02:20 -0400267 return current_calls;
268 }
269
alision43a9b362013-05-01 16:30:15 -0400270 // Enforce same thread contract to ensure we do not call from somewhere else
271 public class SameThreadException extends Exception {
272 private static final long serialVersionUID = -905639124232613768L;
273
274 public SameThreadException() {
275 super("Should be launched from a single worker thread");
276 }
277 }
278
279 public abstract static class SipRunnable implements Runnable {
280 protected abstract void doRun() throws SameThreadException, RemoteException;
281
Adrien Béraud9360f242013-09-19 11:07:42 +1000282 @Override
alision43a9b362013-05-01 16:30:15 -0400283 public void run() {
284 try {
285 doRun();
286 } catch (SameThreadException e) {
287 Log.e(TAG, "Not done from same thread");
288 } catch (RemoteException e) {
289 Log.e(TAG, e.toString());
290 }
291 }
292 }
293
294 public abstract static class SipRunnableWithReturn implements Runnable {
295 Object obj = null;
296 boolean done = false;
297
298 protected abstract Object doRun() throws SameThreadException;
299
300 public Object getVal() {
301 return obj;
302 }
303
304 public boolean isDone() {
305 return done;
306 }
307
Adrien Béraud9360f242013-09-19 11:07:42 +1000308 @Override
alision43a9b362013-05-01 16:30:15 -0400309 public void run() {
310 try {
311 obj = doRun();
312 done = true;
313 } catch (SameThreadException e) {
314 Log.e(TAG, "Not done from same thread");
315 }
316 }
317 }
318
319 class StartRunnable extends SipRunnable {
320 @Override
321 protected void doRun() throws SameThreadException {
322 startPjSipStack();
323 }
324 }
325
326 private class SipServiceThread extends Thread {
327
328 public SipServiceThread() {
329 super("sipServiceThread");
330 }
331
332 @Override
333 public void run() {
334 Log.i(TAG, "SipService thread running...");
335 SipService sipService = SipService.this;
336 while (sipService.runFlag) {
337 try {
338 Thread.sleep(DELAY);
339 } catch (InterruptedException e) {
340 sipService.runFlag = false;
341 Log.w(TAG, "service thread interrupted!");
342 }
343 }
344 }
345 }
346
347 /* ************************************
348 *
349 * Implement public interface for the service
350 *
Alexandre Lision67817192013-07-18 12:04:30 -0400351 * *********************************
352 */
353
Emeric Vigier6119d782012-09-21 18:04:14 -0400354 private final ISipService.Stub mBinder = new ISipService.Stub() {
355
356 @Override
alisionfde875f2013-05-28 17:01:54 -0400357 public void placeCall(final SipCall call) {
Emeric Vigier6119d782012-09-21 18:04:14 -0400358 getExecutor().execute(new SipRunnable() {
359 @Override
360 protected void doRun() throws SameThreadException {
361 Log.i(TAG, "SipService.placeCall() thread running...");
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400362 callManagerJNI.placeCall(call.getAccount().getAccountID(), call.getCallId(), call.getContact().getPhones().get(0).getNumber());
Adrien Béraud9360f242013-09-19 11:07:42 +1000363
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400364 HashMap<String, String> details = CallDetailsHandler.convertSwigToNative(callManagerJNI.getCallDetails(call.getCallId()));
Alexandre Lisionebeb3662013-09-17 16:20:54 -0400365 // watchout timestamp stored by sflphone is in seconds
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400366 call.setTimestamp_start(Long.parseLong(details.get(ServiceConstants.call.TIMESTAMP_START)));
alision2cb99562013-05-30 17:02:20 -0400367 getCurrent_calls().put(call.getCallId(), call);
Adrien Béraud9360f242013-09-19 11:07:42 +1000368
Emeric Vigier6119d782012-09-21 18:04:14 -0400369 }
370 });
371 }
372
373 @Override
374 public void refuse(final String callID) {
375 getExecutor().execute(new SipRunnable() {
376 @Override
377 protected void doRun() throws SameThreadException {
378 Log.i(TAG, "SipService.refuse() thread running...");
379 callManagerJNI.refuse(callID);
380 }
381 });
382 }
383
384 @Override
385 public void accept(final String callID) {
386 getExecutor().execute(new SipRunnable() {
387 @Override
388 protected void doRun() throws SameThreadException {
Tristan Matthews40cf25e2013-07-24 13:45:15 -0400389 Log.i(TAG, "SipService.accept() thread running...");
Emeric Vigier6119d782012-09-21 18:04:14 -0400390 callManagerJNI.accept(callID);
391 }
392 });
393 }
394
395 @Override
396 public void hangUp(final String callID) {
397 getExecutor().execute(new SipRunnable() {
398 @Override
399 protected void doRun() throws SameThreadException {
400 Log.i(TAG, "SipService.hangUp() thread running...");
401 callManagerJNI.hangUp(callID);
402 }
403 });
404 }
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400405
406 @Override
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400407 public void hold(final String callID) {
408 getExecutor().execute(new SipRunnable() {
409 @Override
410 protected void doRun() throws SameThreadException {
411 Log.i(TAG, "SipService.hold() thread running...");
412 callManagerJNI.hold(callID);
413 }
414 });
415 }
416
417 @Override
418 public void unhold(final String callID) {
419 getExecutor().execute(new SipRunnable() {
420 @Override
421 protected void doRun() throws SameThreadException {
422 Log.i(TAG, "SipService.unhold() thread running...");
423 callManagerJNI.unhold(callID);
424 }
425 });
426 }
Adrien Béraud9360f242013-09-19 11:07:42 +1000427
Alexandre Lision6711ab22013-09-16 15:15:38 -0400428 @Override
429 public HashMap<String, String> getCallDetails(String callID) throws RemoteException {
430 class CallDetails extends SipRunnableWithReturn {
431 private String id;
432
433 CallDetails(String callID) {
434 id = callID;
435 }
436
437 @Override
438 protected StringMap doRun() throws SameThreadException {
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400439 Log.i(TAG, "SipService.getCallDetails() thread running...");
Alexandre Lision6711ab22013-09-16 15:15:38 -0400440 return callManagerJNI.getCallDetails(id);
441 }
442 }
443
444 CallDetails runInstance = new CallDetails(callID);
445 getExecutor().execute(runInstance);
446
447 while (!runInstance.isDone()) {
448 }
449 StringMap swigmap = (StringMap) runInstance.getVal();
450
451 HashMap<String, String> nativemap = CallDetailsHandler.convertSwigToNative(swigmap);
452
453 return nativemap;
Adrien Béraud9360f242013-09-19 11:07:42 +1000454
Alexandre Lision6711ab22013-09-16 15:15:38 -0400455 }
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400456
457 @Override
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400458 public void setAudioPlugin(final String audioPlugin) {
459 getExecutor().execute(new SipRunnable() {
alision371b77e2013-04-23 14:51:26 -0400460 @Override
461 protected void doRun() throws SameThreadException {
462 Log.i(TAG, "SipService.setAudioPlugin() thread running...");
463 configurationManagerJNI.setAudioPlugin(audioPlugin);
464 }
Alexandre Savard31d27c62012-10-04 16:05:08 -0400465 });
466 }
467
468 @Override
469 public String getCurrentAudioOutputPlugin() {
470 class CurrentAudioPlugin extends SipRunnableWithReturn {
471 @Override
472 protected String doRun() throws SameThreadException {
473 Log.i(TAG, "SipService.getCurrentAudioOutputPlugin() thread running...");
474 return configurationManagerJNI.getCurrentAudioOutputPlugin();
475 }
alision371b77e2013-04-23 14:51:26 -0400476 }
477 ;
Alexandre Savard31d27c62012-10-04 16:05:08 -0400478
479 CurrentAudioPlugin runInstance = new CurrentAudioPlugin();
480 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400481 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400482 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400483 }
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400484 return (String) runInstance.getVal();
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400485 }
Alexandre Savard713a34d2012-09-26 15:50:41 -0400486
487 @Override
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400488 public ArrayList<String> getAccountList() {
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400489 class AccountList extends SipRunnableWithReturn {
490 @Override
491 protected StringVect doRun() throws SameThreadException {
492 Log.i(TAG, "SipService.getAccountList() thread running...");
493 return configurationManagerJNI.getAccountList();
494 }
alision371b77e2013-04-23 14:51:26 -0400495 }
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400496 AccountList runInstance = new AccountList();
Alexandre Lisioncdec5952013-07-17 14:18:22 -0400497 Log.i(TAG, "SipService.getAccountList() thread running...");
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400498 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400499 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400500 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400501 }
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400502 StringVect swigvect = (StringVect) runInstance.getVal();
503
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400504 ArrayList<String> nativelist = new ArrayList<String>();
Alexandre Savard52a72522012-09-27 16:40:13 -0400505
alision371b77e2013-04-23 14:51:26 -0400506 for (int i = 0; i < swigvect.size(); i++)
507 nativelist.add(swigvect.get(i));
Alexandre Savard52a72522012-09-27 16:40:13 -0400508
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400509 return nativelist;
alision371b77e2013-04-23 14:51:26 -0400510 }
Alexandre Lision4cf78702013-10-16 13:43:23 -0400511
512 @Override
513 public void setAccountOrder(final String order){
514 getExecutor().execute(new SipRunnable() {
515 @Override
516 protected void doRun() throws SameThreadException {
517 Log.i(TAG, "SipService.setAccountsOrder() thread running...");
518 configurationManagerJNI.setAccountsOrder(order);
519 }
520 });
521 }
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400522
523 @Override
alision371b77e2013-04-23 14:51:26 -0400524 public HashMap<String, String> getAccountDetails(final String accountID) {
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400525 class AccountDetails extends SipRunnableWithReturn {
526 private String id;
alision371b77e2013-04-23 14:51:26 -0400527
528 AccountDetails(String accountId) {
529 id = accountId;
530 }
531
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400532 @Override
533 protected StringMap doRun() throws SameThreadException {
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400534 Log.i(TAG, "SipService.getAccountDetails() thread running...");
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400535 return configurationManagerJNI.getAccountDetails(id);
536 }
alision371b77e2013-04-23 14:51:26 -0400537 }
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400538
539 AccountDetails runInstance = new AccountDetails(accountID);
540 getExecutor().execute(runInstance);
alisionfde875f2013-05-28 17:01:54 -0400541
alision371b77e2013-04-23 14:51:26 -0400542 while (!runInstance.isDone()) {
543 }
544 StringMap swigmap = (StringMap) runInstance.getVal();
Alexandre Savard713a34d2012-09-26 15:50:41 -0400545
Alexandre Savard3bbb4792012-10-05 11:30:01 -0400546 HashMap<String, String> nativemap = AccountDetailsHandler.convertSwigToNative(swigmap);
Alexandre Savard713a34d2012-09-26 15:50:41 -0400547
548 return nativemap;
549 }
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400550
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400551 @SuppressWarnings("unchecked")
552 // Hashmap runtime cast
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400553 @Override
alisioncc7bb422013-06-06 15:31:39 -0400554 public void setAccountDetails(final String accountId, final Map map) {
alision371b77e2013-04-23 14:51:26 -0400555 HashMap<String, String> nativemap = (HashMap<String, String>) map;
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400556
Alexandre Savard3bbb4792012-10-05 11:30:01 -0400557 final StringMap swigmap = AccountDetailsHandler.convertFromNativeToSwig(nativemap);
Alexandre Savard718d49f2012-10-02 15:17:13 -0400558
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400559 getExecutor().execute(new SipRunnable() {
560 @Override
561 protected void doRun() throws SameThreadException {
alisioncc7bb422013-06-06 15:31:39 -0400562
563 configurationManagerJNI.setCredentials(accountId, extractCredentials(map));
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400564 configurationManagerJNI.setAccountDetails(accountId, swigmap);
alisioncc7bb422013-06-06 15:31:39 -0400565
Alexandre Lisionafd40e42013-10-15 13:48:37 -0400566 // convertSwigToNative(configurationManagerJNI.getCredentials(accountId));
alisioncc7bb422013-06-06 15:31:39 -0400567 Log.i(TAG, "SipService.setAccountDetails() thread running...");
568 }
569
570 private VectMap extractCredentials(Map map) {
571 VectMap swigmap = new VectMap();
572 StringMap entry = new StringMap();
alision5cfc35d2013-07-11 15:11:39 -0400573 entry.set(AccountDetailBasic.CONFIG_ACCOUNT_USERNAME, (String) map.get(AccountDetailBasic.CONFIG_ACCOUNT_USERNAME));
574 if ((String) map.get(AccountDetailBasic.CONFIG_ACCOUNT_REALM) != null)
575 entry.set(AccountDetailBasic.CONFIG_ACCOUNT_REALM, (String) map.get(AccountDetailBasic.CONFIG_ACCOUNT_REALM));
alisioncc7bb422013-06-06 15:31:39 -0400576 else
alision5cfc35d2013-07-11 15:11:39 -0400577 entry.set(AccountDetailBasic.CONFIG_ACCOUNT_REALM, "*");
578 entry.set(AccountDetailBasic.CONFIG_ACCOUNT_PASSWORD, (String) map.get(AccountDetailBasic.CONFIG_ACCOUNT_PASSWORD));
alisioncc7bb422013-06-06 15:31:39 -0400579 swigmap.add(entry);
580 return swigmap;
581
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400582 }
583 });
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400584 }
585
Alexandre Lisionafd40e42013-10-15 13:48:37 -0400586 // public ArrayList<HashMap<String, String>> convertSwigToNative(VectMap swigmap) {
587 //
588 // ArrayList<HashMap<String, String>> nativemap = new ArrayList<HashMap<String, String>>();
589 // Log.i(TAG, "swigmap size " + swigmap.size());
590 // for (int i = 0; i < swigmap.size(); ++i) {
591 // Log.i(TAG, "Entry " + i);
592 // StringMap tmp = swigmap.get(i);
593 // Log.i(TAG, tmp.get(AccountDetailBasic.CONFIG_ACCOUNT_USERNAME));
594 // // Log.i(TAG, tmp.get(ServiceConstants.CONFIG_ACCOUNT_REALM));
595 // Log.i(TAG, tmp.get(AccountDetailBasic.CONFIG_ACCOUNT_PASSWORD));
596 // }
597 //
598 // return nativemap;
599 // }
alisioncc7bb422013-06-06 15:31:39 -0400600
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400601 @SuppressWarnings("unchecked")
602 // Hashmap runtime cast
Alexandre Savard46036572012-10-05 13:56:49 -0400603 @Override
604 public String addAccount(Map map) {
605 class AddAccount extends SipRunnableWithReturn {
606 StringMap map;
alision371b77e2013-04-23 14:51:26 -0400607
608 AddAccount(StringMap m) {
609 map = m;
610 }
611
Alexandre Savard46036572012-10-05 13:56:49 -0400612 @Override
613 protected String doRun() throws SameThreadException {
614 Log.i(TAG, "SipService.getAccountDetails() thread running...");
615 return configurationManagerJNI.addAccount(map);
616 }
alision371b77e2013-04-23 14:51:26 -0400617 }
Alexandre Savard46036572012-10-05 13:56:49 -0400618
alision371b77e2013-04-23 14:51:26 -0400619 final StringMap swigmap = AccountDetailsHandler.convertFromNativeToSwig((HashMap<String, String>) map);
Alexandre Savard46036572012-10-05 13:56:49 -0400620
621 AddAccount runInstance = new AddAccount(swigmap);
622 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400623 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400624 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400625 }
Alexandre Savard46036572012-10-05 13:56:49 -0400626 String accountId = (String) runInstance.getVal();
627
628 return accountId;
629 }
630
631 @Override
632 public void removeAccount(final String accountId) {
633 getExecutor().execute(new SipRunnable() {
634 @Override
635 protected void doRun() throws SameThreadException {
636 Log.i(TAG, "SipService.setAccountDetails() thread running...");
637 configurationManagerJNI.removeAccount(accountId);
638 }
639 });
640 }
alision5f899632013-04-22 17:26:56 -0400641
alisione2a38e12013-04-25 14:20:20 -0400642 @Override
643 public ArrayList<HashMap<String, String>> getHistory() throws RemoteException {
644 class History extends SipRunnableWithReturn {
645
646 @Override
647 protected VectMap doRun() throws SameThreadException {
648 Log.i(TAG, "SipService.getHistory() thread running...");
alision7f18fc82013-05-01 09:37:33 -0400649
alisione2a38e12013-04-25 14:20:20 -0400650 return configurationManagerJNI.getHistory();
651 }
652 }
653
654 History runInstance = new History();
655 getExecutor().execute(runInstance);
656 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400657 // Log.w(TAG, "Waiting for getHistory");
alisione2a38e12013-04-25 14:20:20 -0400658 }
alision1005ba12013-06-19 13:52:44 -0400659 Log.i(TAG, "SipService.getHistory() DONE");
alisione2a38e12013-04-25 14:20:20 -0400660 VectMap swigmap = (VectMap) runInstance.getVal();
661
662 ArrayList<HashMap<String, String>> nativemap = HistoryHandler.convertSwigToNative(swigmap);
663
664 return nativemap;
665 }
alision7f18fc82013-05-01 09:37:33 -0400666
alision43a9b362013-05-01 16:30:15 -0400667 /*************************
668 * Transfer related API
669 *************************/
670
alision7f18fc82013-05-01 09:37:33 -0400671 @Override
672 public void transfer(final String callID, final String to) throws RemoteException {
673 getExecutor().execute(new SipRunnable() {
674 @Override
675 protected void doRun() throws SameThreadException, RemoteException {
676 Log.i(TAG, "SipService.transfer() thread running...");
677 if (callManagerJNI.transfer(callID, to)) {
678 Bundle bundle = new Bundle();
679 bundle.putString("CallID", callID);
680 bundle.putString("State", "HUNGUP");
681 Intent intent = new Intent(CallManagerCallBack.CALL_STATE_CHANGED);
alision7f18fc82013-05-01 09:37:33 -0400682 intent.putExtra("com.savoirfairelinux.sflphone.service.newstate", bundle);
alision84813a12013-05-27 17:40:39 -0400683 sendBroadcast(intent);
alision7f18fc82013-05-01 09:37:33 -0400684 } else
685 Log.i(TAG, "NOT OK");
686 }
687 });
688
689 }
alision43a9b362013-05-01 16:30:15 -0400690
alision7f18fc82013-05-01 09:37:33 -0400691 @Override
692 public void attendedTransfer(final String transferID, final String targetID) throws RemoteException {
693 getExecutor().execute(new SipRunnable() {
694 @Override
695 protected void doRun() throws SameThreadException, RemoteException {
alision43a9b362013-05-01 16:30:15 -0400696 Log.i(TAG, "SipService.attendedTransfer() thread running...");
alision7f18fc82013-05-01 09:37:33 -0400697 if (callManagerJNI.attendedTransfer(transferID, targetID)) {
698 Log.i(TAG, "OK");
alision7f18fc82013-05-01 09:37:33 -0400699 } else
700 Log.i(TAG, "NOT OK");
701 }
702 });
alision43a9b362013-05-01 16:30:15 -0400703
704 }
705
706 /*************************
707 * Conference related API
708 *************************/
709
710 @Override
711 public void removeConference(final String confID) throws RemoteException {
712 getExecutor().execute(new SipRunnable() {
713 @Override
714 protected void doRun() throws SameThreadException, RemoteException {
715 Log.i(TAG, "SipService.createConference() thread running...");
716 callManagerJNI.removeConference(confID);
717 }
718 });
719
alision7f18fc82013-05-01 09:37:33 -0400720 }
721
722 @Override
alision43a9b362013-05-01 16:30:15 -0400723 public void joinParticipant(final String sel_callID, final String drag_callID) throws RemoteException {
724 getExecutor().execute(new SipRunnable() {
725 @Override
726 protected void doRun() throws SameThreadException, RemoteException {
727 Log.i(TAG, "SipService.joinParticipant() thread running...");
728 callManagerJNI.joinParticipant(sel_callID, drag_callID);
alision806e18e2013-06-21 15:30:17 -0400729 // Generate a CONF_CREATED callback
alision43a9b362013-05-01 16:30:15 -0400730 }
731 });
732
alision7f18fc82013-05-01 09:37:33 -0400733 }
734
alision7f18fc82013-05-01 09:37:33 -0400735 @Override
alision806e18e2013-06-21 15:30:17 -0400736 public void addParticipant(final SipCall call, final String confID) throws RemoteException {
alision43a9b362013-05-01 16:30:15 -0400737 getExecutor().execute(new SipRunnable() {
738 @Override
739 protected void doRun() throws SameThreadException, RemoteException {
740 Log.i(TAG, "SipService.addParticipant() thread running...");
alision806e18e2013-06-21 15:30:17 -0400741 callManagerJNI.addParticipant(call.getCallId(), confID);
742 current_confs.get(confID).getParticipants().add(call);
alision43a9b362013-05-01 16:30:15 -0400743 }
744 });
745
alision7f18fc82013-05-01 09:37:33 -0400746 }
747
748 @Override
alision43a9b362013-05-01 16:30:15 -0400749 public void addMainParticipant(final String confID) throws RemoteException {
750 getExecutor().execute(new SipRunnable() {
751 @Override
752 protected void doRun() throws SameThreadException, RemoteException {
753 Log.i(TAG, "SipService.addMainParticipant() thread running...");
754 callManagerJNI.addMainParticipant(confID);
755 }
756 });
757
alision7f18fc82013-05-01 09:37:33 -0400758 }
759
760 @Override
alision43a9b362013-05-01 16:30:15 -0400761 public void detachParticipant(final String callID) throws RemoteException {
762 getExecutor().execute(new SipRunnable() {
763 @Override
764 protected void doRun() throws SameThreadException, RemoteException {
765 Log.i(TAG, "SipService.detachParticipant() thread running...");
alision806e18e2013-06-21 15:30:17 -0400766 Log.i(TAG, "Detaching " + callID);
767 Iterator<Entry<String, Conference>> it = current_confs.entrySet().iterator();
768 Log.i(TAG, "current_confs size " + current_confs.size());
769 while (it.hasNext()) {
770 Conference tmp = it.next().getValue();
771 Log.i(TAG, "conf has " + tmp.getParticipants().size() + " participants");
772 if (tmp.contains(callID)) {
773 current_calls.put(callID, tmp.getCall(callID));
774 Log.i(TAG, "Call found and put in current_calls");
775 }
776 }
alision43a9b362013-05-01 16:30:15 -0400777 callManagerJNI.detachParticipant(callID);
778 }
779 });
780
alision7f18fc82013-05-01 09:37:33 -0400781 }
782
783 @Override
alision43a9b362013-05-01 16:30:15 -0400784 public void joinConference(final String sel_confID, final String drag_confID) throws RemoteException {
785 getExecutor().execute(new SipRunnable() {
786 @Override
787 protected void doRun() throws SameThreadException, RemoteException {
788 Log.i(TAG, "SipService.joinConference() thread running...");
789 callManagerJNI.joinConference(sel_confID, drag_confID);
790 }
791 });
792
alision7f18fc82013-05-01 09:37:33 -0400793 }
794
795 @Override
alision43a9b362013-05-01 16:30:15 -0400796 public void hangUpConference(final String confID) throws RemoteException {
797 getExecutor().execute(new SipRunnable() {
798 @Override
799 protected void doRun() throws SameThreadException, RemoteException {
800 Log.i(TAG, "SipService.joinConference() thread running...");
801 callManagerJNI.hangUpConference(confID);
802 }
803 });
804
alision7f18fc82013-05-01 09:37:33 -0400805 }
806
807 @Override
alision43a9b362013-05-01 16:30:15 -0400808 public void holdConference(final String confID) throws RemoteException {
809 getExecutor().execute(new SipRunnable() {
810 @Override
811 protected void doRun() throws SameThreadException, RemoteException {
812 Log.i(TAG, "SipService.holdConference() thread running...");
813 callManagerJNI.holdConference(confID);
814 }
815 });
816
alision7f18fc82013-05-01 09:37:33 -0400817 }
818
819 @Override
alision43a9b362013-05-01 16:30:15 -0400820 public void unholdConference(final String confID) throws RemoteException {
821 getExecutor().execute(new SipRunnable() {
822 @Override
823 protected void doRun() throws SameThreadException, RemoteException {
824 Log.i(TAG, "SipService.unholdConference() thread running...");
825 callManagerJNI.unholdConference(confID);
826 }
827 });
828
alision7f18fc82013-05-01 09:37:33 -0400829 }
Alexandre Lision67817192013-07-18 12:04:30 -0400830
alisioncd8fb912013-06-28 14:43:51 -0400831 @Override
832 public boolean isConferenceParticipant(final String callID) throws RemoteException {
833 class IsParticipant extends SipRunnableWithReturn {
834
835 @Override
836 protected Boolean doRun() throws SameThreadException {
837 Log.i(TAG, "SipService.isRecording() thread running...");
838 return callManagerJNI.isConferenceParticipant(callID);
839 }
840 }
841
842 IsParticipant runInstance = new IsParticipant();
843 getExecutor().execute(runInstance);
844 while (!runInstance.isDone()) {
845 }
846
847 return (Boolean) runInstance.getVal();
848 }
alision7f18fc82013-05-01 09:37:33 -0400849
850 @Override
alisiondf1dac92013-06-27 17:35:53 -0400851 public HashMap<String, Conference> getConferenceList() throws RemoteException {
Alexandre Lision67817192013-07-18 12:04:30 -0400852 // class ConfList extends SipRunnableWithReturn {
853 // @Override
854 // protected StringVect doRun() throws SameThreadException {
855 // Log.i(TAG, "SipService.getConferenceList() thread running...");
856 // return callManagerJNI.getConferenceList();
857 // }
858 // }
859 // ;
860 // ConfList runInstance = new ConfList();
861 // getExecutor().execute(runInstance);
862 // while (!runInstance.isDone()) {
863 // // Log.w(TAG, "Waiting for getConferenceList");
864 // }
865 // StringVect swigvect = (StringVect) runInstance.getVal();
866 //
867 // ArrayList<String> nativelist = new ArrayList<String>();
868 //
869 // for (int i = 0; i < swigvect.size(); i++)
870 // nativelist.add(swigvect.get(i));
871 //
872 // return nativelist;
alisiondf1dac92013-06-27 17:35:53 -0400873 return current_confs;
alision7f18fc82013-05-01 09:37:33 -0400874 }
875
876 @Override
alision907bde72013-06-20 14:40:37 -0400877 public List getParticipantList(final String confID) throws RemoteException {
878 class PartList extends SipRunnableWithReturn {
879 @Override
880 protected StringVect doRun() throws SameThreadException {
881 Log.i(TAG, "SipService.getAccountList() thread running...");
882 return callManagerJNI.getParticipantList(confID);
883 }
884 }
885 ;
886 PartList runInstance = new PartList();
887 getExecutor().execute(runInstance);
888 while (!runInstance.isDone()) {
889 // Log.w(TAG, "Waiting for getConferenceList");
890 }
891 StringVect swigvect = (StringVect) runInstance.getVal();
892
893 ArrayList<String> nativelist = new ArrayList<String>();
894
895 for (int i = 0; i < swigvect.size(); i++)
896 nativelist.add(swigvect.get(i));
897
898 return nativelist;
alision7f18fc82013-05-01 09:37:33 -0400899 }
alision806e18e2013-06-21 15:30:17 -0400900
alision1005ba12013-06-19 13:52:44 -0400901 @Override
alision7f18fc82013-05-01 09:37:33 -0400902 public String getConferenceId(String callID) throws RemoteException {
alision43a9b362013-05-01 16:30:15 -0400903 Log.e(TAG, "getConferenceList not implemented");
alision7f18fc82013-05-01 09:37:33 -0400904 return null;
905 }
906
907 @Override
alision806e18e2013-06-21 15:30:17 -0400908 public String getConferenceDetails(final String callID) throws RemoteException {
909 class ConfDetails extends SipRunnableWithReturn {
910 @Override
911 protected StringMap doRun() throws SameThreadException {
912 Log.i(TAG, "SipService.getAccountList() thread running...");
913 return callManagerJNI.getConferenceDetails(callID);
914 }
915 }
916 ;
917 ConfDetails runInstance = new ConfDetails();
918 getExecutor().execute(runInstance);
919 while (!runInstance.isDone()) {
920 // Log.w(TAG, "Waiting for getConferenceList");
921 }
922 StringMap swigvect = (StringMap) runInstance.getVal();
923
924 return swigvect.get("CONF_STATE");
alision7f18fc82013-05-01 09:37:33 -0400925 }
926
alision04a00182013-05-10 17:05:29 -0400927 @Override
928 public String getRecordPath() throws RemoteException {
929 class RecordPath extends SipRunnableWithReturn {
930
931 @Override
932 protected String doRun() throws SameThreadException {
933 Log.i(TAG, "SipService.getRecordPath() thread running...");
Adrien Béraud9360f242013-09-19 11:07:42 +1000934 return configurationManagerJNI.getRecordPath();
alision04a00182013-05-10 17:05:29 -0400935 }
936 }
937
938 RecordPath runInstance = new RecordPath();
939 getExecutor().execute(runInstance);
940 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400941 // Log.w(TAG, "Waiting for getRecordPath");
alision04a00182013-05-10 17:05:29 -0400942 }
943 String path = (String) runInstance.getVal();
944
945 return path;
946 }
947
948 @Override
Alexandre Lisiona764c682013-09-09 10:02:07 -0400949 public boolean toggleRecordingCall(final String id) throws RemoteException {
Adrien Béraud9360f242013-09-19 11:07:42 +1000950
Alexandre Lisiona764c682013-09-09 10:02:07 -0400951 class ToggleRecording extends SipRunnableWithReturn {
952
alision04a00182013-05-10 17:05:29 -0400953 @Override
Alexandre Lisiona764c682013-09-09 10:02:07 -0400954 protected Boolean doRun() throws SameThreadException {
955 Log.i(TAG, "SipService.toggleRecordingCall() thread running...");
956 return callManagerJNI.toggleRecording(id);
alision04a00182013-05-10 17:05:29 -0400957 }
Alexandre Lisiona764c682013-09-09 10:02:07 -0400958 }
959
960 ToggleRecording runInstance = new ToggleRecording();
961 getExecutor().execute(runInstance);
962 while (!runInstance.isDone()) {
963 }
964
965 return (Boolean) runInstance.getVal();
alision04a00182013-05-10 17:05:29 -0400966
967 }
Alexandre Lision67817192013-07-18 12:04:30 -0400968
alision50fa0722013-06-25 17:29:44 -0400969 @Override
alisiondf1dac92013-06-27 17:35:53 -0400970 public boolean isRecording(final String id) throws RemoteException {
971 class IsRecording extends SipRunnableWithReturn {
972
973 @Override
974 protected Boolean doRun() throws SameThreadException {
975 Log.i(TAG, "SipService.isRecording() thread running...");
976 return callManagerJNI.getIsRecording(id);
977 }
978 }
979
980 IsRecording runInstance = new IsRecording();
981 getExecutor().execute(runInstance);
982 while (!runInstance.isDone()) {
983 }
984
985 return (Boolean) runInstance.getVal();
Alexandre Lision67817192013-07-18 12:04:30 -0400986
alisiondf1dac92013-06-27 17:35:53 -0400987 }
Alexandre Lision67817192013-07-18 12:04:30 -0400988
alisiondf1dac92013-06-27 17:35:53 -0400989 @Override
alision50fa0722013-06-25 17:29:44 -0400990 public boolean startRecordedFilePlayback(final String filepath) throws RemoteException {
991 getExecutor().execute(new SipRunnable() {
992 @Override
993 protected void doRun() throws SameThreadException, RemoteException {
994 Log.i(TAG, "SipService.setRecordingCall() thread running...");
995 callManagerJNI.startRecordedFilePlayback(filepath);
996 }
997 });
998 return false;
999 }
1000
1001 @Override
1002 public void stopRecordedFilePlayback(final String filepath) throws RemoteException {
1003 getExecutor().execute(new SipRunnable() {
1004 @Override
1005 protected void doRun() throws SameThreadException, RemoteException {
1006 Log.i(TAG, "SipService.stopRecordedFilePlayback() thread running...");
1007 callManagerJNI.stopRecordedFilePlayback(filepath);
1008 }
1009 });
1010 }
alision04a00182013-05-10 17:05:29 -04001011
1012 @Override
1013 public void setRecordPath(final String path) throws RemoteException {
1014 getExecutor().execute(new SipRunnable() {
1015 @Override
1016 protected void doRun() throws SameThreadException, RemoteException {
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001017 Log.i(TAG, "SipService.setRecordPath() " + path + " thread running...");
Adrien Béraud9360f242013-09-19 11:07:42 +10001018 configurationManagerJNI.setRecordPath(path);
alision04a00182013-05-10 17:05:29 -04001019 }
1020 });
1021 }
1022
1023 @Override
1024 public void sendTextMessage(final String callID, final String message, final String from) throws RemoteException {
1025 getExecutor().execute(new SipRunnable() {
1026 @Override
1027 protected void doRun() throws SameThreadException, RemoteException {
1028 Log.i(TAG, "SipService.sendTextMessage() thread running...");
Alexandre Lision10314352013-07-17 15:06:56 -04001029 callManagerJNI.sendTextMessage(callID, message);
alision04a00182013-05-10 17:05:29 -04001030 }
1031 });
1032
1033 }
1034
alisiond295ec22013-05-17 10:12:13 -04001035 @Override
Alexandre Lision4cf78702013-10-16 13:43:23 -04001036 public List getAudioCodecList(final String accountID) throws RemoteException {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001037 class AudioCodecList extends SipRunnableWithReturn {
1038
1039 @Override
Alexandre Lision933ef0a2013-10-15 17:28:40 -04001040 protected ArrayList<Codec> doRun() throws SameThreadException {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001041 Log.i(TAG, "SipService.getAudioCodecList() thread running...");
Alexandre Lision4cf78702013-10-16 13:43:23 -04001042 HashMap<Integer, Codec> results = new HashMap<Integer, Codec>();
1043
1044 IntVect active_payloads = configurationManagerJNI.getActiveAudioCodecList(accountID);
1045 for (int i = 0; i < active_payloads.size(); ++i) {
1046
1047 results.put(active_payloads.get(i),
1048 new Codec(active_payloads.get(i), configurationManagerJNI.getAudioCodecDetails(active_payloads.get(i)), true));
1049 Log.i(TAG, "Active, Adding:" + results.get((active_payloads.get(i))).getName());
Alexandre Lision933ef0a2013-10-15 17:28:40 -04001050 }
Alexandre Lision4cf78702013-10-16 13:43:23 -04001051
1052 IntVect payloads = configurationManagerJNI.getAudioCodecList();
1053
1054 for (int i = 0; i < payloads.size(); ++i) {
1055 if (!results.containsKey(payloads.get(i))) {
1056 results.put(payloads.get(i), new Codec(payloads.get(i), configurationManagerJNI.getAudioCodecDetails(payloads.get(i)),
1057 false));
1058 Log.i(TAG, "Other, Adding:" + results.get((payloads.get(i))).getName());
1059 }
1060 }
1061 return new ArrayList<Codec>(results.values());
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001062 }
1063 }
1064
1065 AudioCodecList runInstance = new AudioCodecList();
1066 getExecutor().execute(runInstance);
1067 while (!runInstance.isDone()) {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001068 }
Alexandre Lision933ef0a2013-10-15 17:28:40 -04001069 ArrayList<Codec> codecs = (ArrayList<Codec>) runInstance.getVal();
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001070 return codecs;
alisiond295ec22013-05-17 10:12:13 -04001071 }
1072
alision9f7a6ec2013-05-24 16:26:26 -04001073 @Override
Alexandre Lision4cf78702013-10-16 13:43:23 -04001074 public Map getRingtoneList() throws RemoteException {
1075 class RingtoneList extends SipRunnableWithReturn {
1076
1077 @Override
1078 protected StringMap doRun() throws SameThreadException {
1079 Log.i(TAG, "SipService.getRingtoneList() thread running...");
1080 return configurationManagerJNI.getRingtoneList();
1081 }
1082 }
1083
1084 RingtoneList runInstance = new RingtoneList();
1085 getExecutor().execute(runInstance);
1086 while (!runInstance.isDone()) {
1087 }
1088 ArrayList<Codec> codecs = (ArrayList<Codec>) runInstance.getVal();
1089 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
1107 @Override
alisionfde875f2013-05-28 17:01:54 -04001108 public HashMap<String, SipCall> getCallList() throws RemoteException {
alision85704182013-05-29 15:23:03 -04001109 // class CallList extends SipRunnableWithReturn {
1110 //
1111 // @Override
1112 // protected StringVect doRun() throws SameThreadException {
1113 // Log.i(TAG, "SipService.getCallList() thread running...");
1114 // return callManagerJNI.getCallList();
1115 // }
1116 // }
1117 //
1118 // CallList runInstance = new CallList();
1119 // getExecutor().execute(runInstance);
1120 // while (!runInstance.isDone()) {
1121 // Log.w(TAG, "Waiting for getAudioCodecList");
1122 // }
1123 // StringVect swigmap = (StringVect) runInstance.getVal();
1124 //
1125 // ArrayList<String> nativemap = new ArrayList<String>();
1126 // for (int i = 0; i < swigmap.size(); ++i) {
1127 //
1128 // String t = swigmap.get(i);
1129 // nativemap.add(t);
1130 // }
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001131 // if(callManagerJNI == null)
1132 // return new HashMap<String, SipCall>();
1133 //
1134 //
1135 // HashMap<String, SipCall> results = new HashMap<String, SipCall>();
1136 // StringVect calls = callManagerJNI.getCallList();
1137 // for(int i = 0 ; i < calls.size(); ++i){
1138 // results.put(calls.get(i), new SipCall(calls.get(i), callManagerJNI.getCallDetails(calls.get(i))));
1139 // }
alision9f7a6ec2013-05-24 16:26:26 -04001140
alision2cb99562013-05-30 17:02:20 -04001141 return getCurrent_calls();
alision9f7a6ec2013-05-24 16:26:26 -04001142 }
1143
alision85704182013-05-29 15:23:03 -04001144 @Override
1145 public SipCall getCall(String callID) throws RemoteException {
alision2cb99562013-05-30 17:02:20 -04001146 return getCurrent_calls().get(callID);
1147 }
1148
1149 /***********************
1150 * Notification API
1151 ***********************/
1152 @Override
1153 public void createNotification() throws RemoteException {
1154 makeNotification();
alisioncc7bb422013-06-06 15:31:39 -04001155
alision2cb99562013-05-30 17:02:20 -04001156 }
1157
1158 @Override
1159 public void destroyNotification() throws RemoteException {
1160 removeNotification();
alisioncc7bb422013-06-06 15:31:39 -04001161
alision2cb99562013-05-30 17:02:20 -04001162 }
alisioncc7bb422013-06-06 15:31:39 -04001163
Adrien Béraud9360f242013-09-19 11:07:42 +10001164 private final int NOTIFICATION_ID = new Random().nextInt(1000);
alisioncc7bb422013-06-06 15:31:39 -04001165
alision2cb99562013-05-30 17:02:20 -04001166 private void makeNotification() {
alisioncc7bb422013-06-06 15:31:39 -04001167 if (current_calls.size() == 0) {
alision2cb99562013-05-30 17:02:20 -04001168 return;
1169 }
1170 Intent notificationIntent = new Intent(getApplicationContext(), SFLPhoneHomeActivity.class);
alisioncc7bb422013-06-06 15:31:39 -04001171 PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 007, notificationIntent,
1172 PendingIntent.FLAG_UPDATE_CURRENT);
alision2cb99562013-05-30 17:02:20 -04001173
1174 NotificationManager nm = (NotificationManager) getBaseContext().getSystemService(Context.NOTIFICATION_SERVICE);
Adrien Béraud9360f242013-09-19 11:07:42 +10001175 nm.cancel(NOTIFICATION_ID); // clear previous notifications.
alision2cb99562013-05-30 17:02:20 -04001176
1177 NotificationCompat.Builder builder = new NotificationCompat.Builder(getBaseContext());
alisioncc7bb422013-06-06 15:31:39 -04001178 //
1179 // builder.setContent(view);
1180 builder.setContentIntent(contentIntent).setOngoing(true).setSmallIcon(R.drawable.ic_launcher)
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001181 .setContentTitle(getCurrent_calls().size() + " ongoing calls").setTicker("Pending calls").setWhen(System.currentTimeMillis())
1182 .setAutoCancel(false);
alision2cb99562013-05-30 17:02:20 -04001183 builder.setPriority(NotificationCompat.PRIORITY_MAX);
1184 Notification n = builder.build();
1185
1186 nm.notify(NOTIFICATION_ID, n);
alision2cb99562013-05-30 17:02:20 -04001187 }
1188
1189 public void removeNotification() {
1190 NotificationManager nm = (NotificationManager) getBaseContext().getSystemService(Context.NOTIFICATION_SERVICE);
1191 nm.cancel(NOTIFICATION_ID);
alision85704182013-05-29 15:23:03 -04001192 }
1193
alisiondf1dac92013-06-27 17:35:53 -04001194 @Override
1195 public Conference getCurrentCall() throws RemoteException {
Alexandre Lision67817192013-07-18 12:04:30 -04001196 for (SipCall i : current_calls.values()) {
Adrien Béraud9360f242013-09-19 11:07:42 +10001197
Alexandre Lisionc51ccb12013-09-11 16:00:30 -04001198 // Incoming >> Ongoing
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001199 if (i.isIncoming()) {
Alexandre Lisionc51ccb12013-09-11 16:00:30 -04001200 Conference tmp = new Conference("-1");
1201 tmp.getParticipants().add(i);
1202 return tmp;
1203 }
Adrien Béraud9360f242013-09-19 11:07:42 +10001204
Alexandre Lision67817192013-07-18 12:04:30 -04001205 if (i.isOngoing()) {
alisiondf1dac92013-06-27 17:35:53 -04001206 Conference tmp = new Conference("-1");
1207 tmp.getParticipants().add(i);
1208 return tmp;
1209 }
1210 }
Alexandre Lision67817192013-07-18 12:04:30 -04001211
1212 if (!current_confs.isEmpty()) {
alisiondf1dac92013-06-27 17:35:53 -04001213 return (Conference) current_confs.values().toArray()[0];
1214 }
1215 return null;
1216 }
1217
Alexandre Lision64dc8c02013-09-25 15:32:25 -04001218 @Override
1219 public void playDtmf(final String key) throws RemoteException {
1220 getExecutor().execute(new SipRunnable() {
1221 @Override
1222 protected void doRun() throws SameThreadException, RemoteException {
1223 Log.i(TAG, "SipService.playDtmf() thread running...");
1224 callManagerJNI.playDTMF(key);
1225 }
1226 });
1227 }
1228
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001229 @Override
1230 public List getConcurrentCalls() throws RemoteException {
1231 ArrayList<Conference> toReturn = new ArrayList<Conference>();
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001232
1233 for (SipCall sip : current_calls.values()) {
1234 if (!sip.isCurrent()) {
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001235 Conference tmp = new Conference("-1");
1236 tmp.getParticipants().add(sip);
1237 toReturn.add(tmp);
1238 }
1239 }
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001240
1241 Log.i(TAG, "toReturn SIZE " + toReturn.size());
1242
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001243 return toReturn;
1244 }
1245
Emeric Vigier6119d782012-09-21 18:04:14 -04001246 };
Emeric Vigiereaf2c492012-09-19 14:38:20 -04001247}