blob: db55abca5991c684b43dff7c05975a0037766703 [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");
Alexandre Lision62138172013-10-17 11:52:45 -0400232 System.loadLibrary("codec_speex_nb");
233 System.loadLibrary("codec_speex_ub");
234 System.loadLibrary("codec_speex_wb");
alision43a9b362013-05-01 16:30:15 -0400235 System.loadLibrary("speexresampler");
236 System.loadLibrary("sflphone");
237 isPjSipStackStarted = true;
Adrien Béraud9360f242013-09-19 11:07:42 +1000238
alision43a9b362013-05-01 16:30:15 -0400239 } catch (UnsatisfiedLinkError e) {
240 Log.e(TAG, "Problem with the current Pj stack...", e);
241 isPjSipStackStarted = false;
242 return;
243 } catch (Exception e) {
244 Log.e(TAG, "Problem with the current Pj stack...", e);
245 }
246
Alexandre Lision67817192013-07-18 12:04:30 -0400247 Log.i(TAG, "PjSIPStack started");
248 managerImpl = SFLPhoneservice.instance();
249
250 /* set static AppPath before calling manager.init */
251
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400252 // managerImpl.setPath(sflphoneApp.getAppPath());
alision43a9b362013-05-01 16:30:15 -0400253
alision3ea8f3c2013-07-16 17:35:35 -0400254 callManagerJNI = new CallManager();
alision43a9b362013-05-01 16:30:15 -0400255 callManagerCallBack = new CallManagerCallBack(this);
256 SFLPhoneservice.setCallbackObject(callManagerCallBack);
257
alision3ea8f3c2013-07-16 17:35:35 -0400258 configurationManagerJNI = new ConfigurationManager();
alision43a9b362013-05-01 16:30:15 -0400259 configurationManagerCallback = new ConfigurationManagerCallback(this);
260 SFLPhoneservice.setConfigurationCallbackObject(configurationManagerCallback);
Adrien Béraud9360f242013-09-19 11:07:42 +1000261
Alexandre Lision67817192013-07-18 12:04:30 -0400262 Log.i(TAG, "before init");
263 managerImpl.init("");
Adrien Béraud9360f242013-09-19 11:07:42 +1000264
Alexandre Lision67817192013-07-18 12:04:30 -0400265 Log.i(TAG, "->startPjSipStack");
alision43a9b362013-05-01 16:30:15 -0400266
Alexandre Lision08d782a2013-10-18 09:36:35 -0400267
alision43a9b362013-05-01 16:30:15 -0400268 }
269
Adrien Béraud9360f242013-09-19 11:07:42 +1000270 public HashMap<String, SipCall> getCurrent_calls() {
alision2cb99562013-05-30 17:02:20 -0400271 return current_calls;
272 }
273
alision43a9b362013-05-01 16:30:15 -0400274 // Enforce same thread contract to ensure we do not call from somewhere else
275 public class SameThreadException extends Exception {
276 private static final long serialVersionUID = -905639124232613768L;
277
278 public SameThreadException() {
279 super("Should be launched from a single worker thread");
280 }
281 }
282
283 public abstract static class SipRunnable implements Runnable {
284 protected abstract void doRun() throws SameThreadException, RemoteException;
285
Adrien Béraud9360f242013-09-19 11:07:42 +1000286 @Override
alision43a9b362013-05-01 16:30:15 -0400287 public void run() {
288 try {
289 doRun();
290 } catch (SameThreadException e) {
291 Log.e(TAG, "Not done from same thread");
292 } catch (RemoteException e) {
293 Log.e(TAG, e.toString());
294 }
295 }
296 }
297
298 public abstract static class SipRunnableWithReturn implements Runnable {
299 Object obj = null;
300 boolean done = false;
301
302 protected abstract Object doRun() throws SameThreadException;
303
304 public Object getVal() {
305 return obj;
306 }
307
308 public boolean isDone() {
309 return done;
310 }
311
Adrien Béraud9360f242013-09-19 11:07:42 +1000312 @Override
alision43a9b362013-05-01 16:30:15 -0400313 public void run() {
314 try {
315 obj = doRun();
316 done = true;
317 } catch (SameThreadException e) {
318 Log.e(TAG, "Not done from same thread");
319 }
320 }
321 }
322
323 class StartRunnable extends SipRunnable {
324 @Override
325 protected void doRun() throws SameThreadException {
326 startPjSipStack();
327 }
328 }
329
330 private class SipServiceThread extends Thread {
331
332 public SipServiceThread() {
333 super("sipServiceThread");
334 }
335
336 @Override
337 public void run() {
338 Log.i(TAG, "SipService thread running...");
339 SipService sipService = SipService.this;
340 while (sipService.runFlag) {
341 try {
342 Thread.sleep(DELAY);
343 } catch (InterruptedException e) {
344 sipService.runFlag = false;
345 Log.w(TAG, "service thread interrupted!");
346 }
347 }
348 }
349 }
350
351 /* ************************************
352 *
353 * Implement public interface for the service
354 *
Alexandre Lision67817192013-07-18 12:04:30 -0400355 * *********************************
356 */
357
Emeric Vigier6119d782012-09-21 18:04:14 -0400358 private final ISipService.Stub mBinder = new ISipService.Stub() {
359
360 @Override
alisionfde875f2013-05-28 17:01:54 -0400361 public void placeCall(final SipCall call) {
Emeric Vigier6119d782012-09-21 18:04:14 -0400362 getExecutor().execute(new SipRunnable() {
363 @Override
364 protected void doRun() throws SameThreadException {
365 Log.i(TAG, "SipService.placeCall() thread running...");
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400366 callManagerJNI.placeCall(call.getAccount().getAccountID(), call.getCallId(), call.getContact().getPhones().get(0).getNumber());
Adrien Béraud9360f242013-09-19 11:07:42 +1000367
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400368 HashMap<String, String> details = CallDetailsHandler.convertSwigToNative(callManagerJNI.getCallDetails(call.getCallId()));
Alexandre Lisionebeb3662013-09-17 16:20:54 -0400369 // watchout timestamp stored by sflphone is in seconds
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400370 call.setTimestamp_start(Long.parseLong(details.get(ServiceConstants.call.TIMESTAMP_START)));
alision2cb99562013-05-30 17:02:20 -0400371 getCurrent_calls().put(call.getCallId(), call);
Adrien Béraud9360f242013-09-19 11:07:42 +1000372
Emeric Vigier6119d782012-09-21 18:04:14 -0400373 }
374 });
375 }
376
377 @Override
378 public void refuse(final String callID) {
379 getExecutor().execute(new SipRunnable() {
380 @Override
381 protected void doRun() throws SameThreadException {
382 Log.i(TAG, "SipService.refuse() thread running...");
383 callManagerJNI.refuse(callID);
384 }
385 });
386 }
387
388 @Override
389 public void accept(final String callID) {
390 getExecutor().execute(new SipRunnable() {
391 @Override
392 protected void doRun() throws SameThreadException {
Tristan Matthews40cf25e2013-07-24 13:45:15 -0400393 Log.i(TAG, "SipService.accept() thread running...");
Emeric Vigier6119d782012-09-21 18:04:14 -0400394 callManagerJNI.accept(callID);
395 }
396 });
397 }
398
399 @Override
400 public void hangUp(final String callID) {
401 getExecutor().execute(new SipRunnable() {
402 @Override
403 protected void doRun() throws SameThreadException {
404 Log.i(TAG, "SipService.hangUp() thread running...");
405 callManagerJNI.hangUp(callID);
406 }
407 });
408 }
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400409
410 @Override
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400411 public void hold(final String callID) {
412 getExecutor().execute(new SipRunnable() {
413 @Override
414 protected void doRun() throws SameThreadException {
415 Log.i(TAG, "SipService.hold() thread running...");
416 callManagerJNI.hold(callID);
417 }
418 });
419 }
420
421 @Override
422 public void unhold(final String callID) {
423 getExecutor().execute(new SipRunnable() {
424 @Override
425 protected void doRun() throws SameThreadException {
426 Log.i(TAG, "SipService.unhold() thread running...");
427 callManagerJNI.unhold(callID);
428 }
429 });
430 }
Adrien Béraud9360f242013-09-19 11:07:42 +1000431
Alexandre Lision6711ab22013-09-16 15:15:38 -0400432 @Override
433 public HashMap<String, String> getCallDetails(String callID) throws RemoteException {
434 class CallDetails extends SipRunnableWithReturn {
435 private String id;
436
437 CallDetails(String callID) {
438 id = callID;
439 }
440
441 @Override
442 protected StringMap doRun() throws SameThreadException {
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400443 Log.i(TAG, "SipService.getCallDetails() thread running...");
Alexandre Lision6711ab22013-09-16 15:15:38 -0400444 return callManagerJNI.getCallDetails(id);
445 }
446 }
447
448 CallDetails runInstance = new CallDetails(callID);
449 getExecutor().execute(runInstance);
450
451 while (!runInstance.isDone()) {
452 }
453 StringMap swigmap = (StringMap) runInstance.getVal();
454
455 HashMap<String, String> nativemap = CallDetailsHandler.convertSwigToNative(swigmap);
456
457 return nativemap;
Adrien Béraud9360f242013-09-19 11:07:42 +1000458
Alexandre Lision6711ab22013-09-16 15:15:38 -0400459 }
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400460
461 @Override
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400462 public void setAudioPlugin(final String audioPlugin) {
463 getExecutor().execute(new SipRunnable() {
alision371b77e2013-04-23 14:51:26 -0400464 @Override
465 protected void doRun() throws SameThreadException {
466 Log.i(TAG, "SipService.setAudioPlugin() thread running...");
467 configurationManagerJNI.setAudioPlugin(audioPlugin);
468 }
Alexandre Savard31d27c62012-10-04 16:05:08 -0400469 });
470 }
471
472 @Override
473 public String getCurrentAudioOutputPlugin() {
474 class CurrentAudioPlugin extends SipRunnableWithReturn {
475 @Override
476 protected String doRun() throws SameThreadException {
477 Log.i(TAG, "SipService.getCurrentAudioOutputPlugin() thread running...");
478 return configurationManagerJNI.getCurrentAudioOutputPlugin();
479 }
alision371b77e2013-04-23 14:51:26 -0400480 }
481 ;
Alexandre Savard31d27c62012-10-04 16:05:08 -0400482
483 CurrentAudioPlugin runInstance = new CurrentAudioPlugin();
484 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400485 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400486 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400487 }
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400488 return (String) runInstance.getVal();
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400489 }
Alexandre Savard713a34d2012-09-26 15:50:41 -0400490
491 @Override
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400492 public ArrayList<String> getAccountList() {
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400493 class AccountList extends SipRunnableWithReturn {
494 @Override
495 protected StringVect doRun() throws SameThreadException {
496 Log.i(TAG, "SipService.getAccountList() thread running...");
497 return configurationManagerJNI.getAccountList();
498 }
alision371b77e2013-04-23 14:51:26 -0400499 }
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400500 AccountList runInstance = new AccountList();
Alexandre Lisioncdec5952013-07-17 14:18:22 -0400501 Log.i(TAG, "SipService.getAccountList() thread running...");
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400502 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400503 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400504 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400505 }
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400506 StringVect swigvect = (StringVect) runInstance.getVal();
507
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400508 ArrayList<String> nativelist = new ArrayList<String>();
Alexandre Savard52a72522012-09-27 16:40:13 -0400509
alision371b77e2013-04-23 14:51:26 -0400510 for (int i = 0; i < swigvect.size(); i++)
511 nativelist.add(swigvect.get(i));
Alexandre Savard52a72522012-09-27 16:40:13 -0400512
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400513 return nativelist;
alision371b77e2013-04-23 14:51:26 -0400514 }
Alexandre Lision4b4233a2013-10-16 17:24:17 -0400515
Alexandre Lision4cf78702013-10-16 13:43:23 -0400516 @Override
Alexandre Lision4b4233a2013-10-16 17:24:17 -0400517 public void setAccountOrder(final String order) {
Alexandre Lision4cf78702013-10-16 13:43:23 -0400518 getExecutor().execute(new SipRunnable() {
519 @Override
520 protected void doRun() throws SameThreadException {
521 Log.i(TAG, "SipService.setAccountsOrder() thread running...");
522 configurationManagerJNI.setAccountsOrder(order);
523 }
524 });
525 }
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400526
527 @Override
alision371b77e2013-04-23 14:51:26 -0400528 public HashMap<String, String> getAccountDetails(final String accountID) {
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400529 class AccountDetails extends SipRunnableWithReturn {
530 private String id;
alision371b77e2013-04-23 14:51:26 -0400531
532 AccountDetails(String accountId) {
533 id = accountId;
534 }
535
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400536 @Override
537 protected StringMap doRun() throws SameThreadException {
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400538 Log.i(TAG, "SipService.getAccountDetails() thread running...");
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400539 return configurationManagerJNI.getAccountDetails(id);
540 }
alision371b77e2013-04-23 14:51:26 -0400541 }
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400542
543 AccountDetails runInstance = new AccountDetails(accountID);
544 getExecutor().execute(runInstance);
alisionfde875f2013-05-28 17:01:54 -0400545
alision371b77e2013-04-23 14:51:26 -0400546 while (!runInstance.isDone()) {
547 }
548 StringMap swigmap = (StringMap) runInstance.getVal();
Alexandre Savard713a34d2012-09-26 15:50:41 -0400549
Alexandre Savard3bbb4792012-10-05 11:30:01 -0400550 HashMap<String, String> nativemap = AccountDetailsHandler.convertSwigToNative(swigmap);
Alexandre Savard713a34d2012-09-26 15:50:41 -0400551
552 return nativemap;
553 }
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400554
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400555 @SuppressWarnings("unchecked")
556 // Hashmap runtime cast
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400557 @Override
alisioncc7bb422013-06-06 15:31:39 -0400558 public void setAccountDetails(final String accountId, final Map map) {
alision371b77e2013-04-23 14:51:26 -0400559 HashMap<String, String> nativemap = (HashMap<String, String>) map;
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400560
Alexandre Savard3bbb4792012-10-05 11:30:01 -0400561 final StringMap swigmap = AccountDetailsHandler.convertFromNativeToSwig(nativemap);
Alexandre Savard718d49f2012-10-02 15:17:13 -0400562
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400563 getExecutor().execute(new SipRunnable() {
564 @Override
565 protected void doRun() throws SameThreadException {
alisioncc7bb422013-06-06 15:31:39 -0400566
567 configurationManagerJNI.setCredentials(accountId, extractCredentials(map));
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400568 configurationManagerJNI.setAccountDetails(accountId, swigmap);
alisioncc7bb422013-06-06 15:31:39 -0400569
Alexandre Lisionafd40e42013-10-15 13:48:37 -0400570 // convertSwigToNative(configurationManagerJNI.getCredentials(accountId));
alisioncc7bb422013-06-06 15:31:39 -0400571 Log.i(TAG, "SipService.setAccountDetails() thread running...");
572 }
573
574 private VectMap extractCredentials(Map map) {
575 VectMap swigmap = new VectMap();
576 StringMap entry = new StringMap();
alision5cfc35d2013-07-11 15:11:39 -0400577 entry.set(AccountDetailBasic.CONFIG_ACCOUNT_USERNAME, (String) map.get(AccountDetailBasic.CONFIG_ACCOUNT_USERNAME));
578 if ((String) map.get(AccountDetailBasic.CONFIG_ACCOUNT_REALM) != null)
579 entry.set(AccountDetailBasic.CONFIG_ACCOUNT_REALM, (String) map.get(AccountDetailBasic.CONFIG_ACCOUNT_REALM));
alisioncc7bb422013-06-06 15:31:39 -0400580 else
alision5cfc35d2013-07-11 15:11:39 -0400581 entry.set(AccountDetailBasic.CONFIG_ACCOUNT_REALM, "*");
582 entry.set(AccountDetailBasic.CONFIG_ACCOUNT_PASSWORD, (String) map.get(AccountDetailBasic.CONFIG_ACCOUNT_PASSWORD));
alisioncc7bb422013-06-06 15:31:39 -0400583 swigmap.add(entry);
584 return swigmap;
585
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400586 }
587 });
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400588 }
589
Alexandre Lisionafd40e42013-10-15 13:48:37 -0400590 // public ArrayList<HashMap<String, String>> convertSwigToNative(VectMap swigmap) {
591 //
592 // ArrayList<HashMap<String, String>> nativemap = new ArrayList<HashMap<String, String>>();
593 // Log.i(TAG, "swigmap size " + swigmap.size());
594 // for (int i = 0; i < swigmap.size(); ++i) {
595 // Log.i(TAG, "Entry " + i);
596 // StringMap tmp = swigmap.get(i);
597 // Log.i(TAG, tmp.get(AccountDetailBasic.CONFIG_ACCOUNT_USERNAME));
598 // // Log.i(TAG, tmp.get(ServiceConstants.CONFIG_ACCOUNT_REALM));
599 // Log.i(TAG, tmp.get(AccountDetailBasic.CONFIG_ACCOUNT_PASSWORD));
600 // }
601 //
602 // return nativemap;
603 // }
alisioncc7bb422013-06-06 15:31:39 -0400604
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400605 @SuppressWarnings("unchecked")
606 // Hashmap runtime cast
Alexandre Savard46036572012-10-05 13:56:49 -0400607 @Override
608 public String addAccount(Map map) {
609 class AddAccount extends SipRunnableWithReturn {
610 StringMap map;
alision371b77e2013-04-23 14:51:26 -0400611
612 AddAccount(StringMap m) {
613 map = m;
614 }
615
Alexandre Savard46036572012-10-05 13:56:49 -0400616 @Override
617 protected String doRun() throws SameThreadException {
618 Log.i(TAG, "SipService.getAccountDetails() thread running...");
619 return configurationManagerJNI.addAccount(map);
620 }
alision371b77e2013-04-23 14:51:26 -0400621 }
Alexandre Savard46036572012-10-05 13:56:49 -0400622
alision371b77e2013-04-23 14:51:26 -0400623 final StringMap swigmap = AccountDetailsHandler.convertFromNativeToSwig((HashMap<String, String>) map);
Alexandre Savard46036572012-10-05 13:56:49 -0400624
625 AddAccount runInstance = new AddAccount(swigmap);
626 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400627 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400628 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400629 }
Alexandre Savard46036572012-10-05 13:56:49 -0400630 String accountId = (String) runInstance.getVal();
631
632 return accountId;
633 }
634
635 @Override
636 public void removeAccount(final String accountId) {
637 getExecutor().execute(new SipRunnable() {
638 @Override
639 protected void doRun() throws SameThreadException {
640 Log.i(TAG, "SipService.setAccountDetails() thread running...");
641 configurationManagerJNI.removeAccount(accountId);
642 }
643 });
644 }
alision5f899632013-04-22 17:26:56 -0400645
alisione2a38e12013-04-25 14:20:20 -0400646 @Override
647 public ArrayList<HashMap<String, String>> getHistory() throws RemoteException {
648 class History extends SipRunnableWithReturn {
649
650 @Override
651 protected VectMap doRun() throws SameThreadException {
652 Log.i(TAG, "SipService.getHistory() thread running...");
alision7f18fc82013-05-01 09:37:33 -0400653
alisione2a38e12013-04-25 14:20:20 -0400654 return configurationManagerJNI.getHistory();
655 }
656 }
657
658 History runInstance = new History();
659 getExecutor().execute(runInstance);
660 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400661 // Log.w(TAG, "Waiting for getHistory");
alisione2a38e12013-04-25 14:20:20 -0400662 }
alision1005ba12013-06-19 13:52:44 -0400663 Log.i(TAG, "SipService.getHistory() DONE");
alisione2a38e12013-04-25 14:20:20 -0400664 VectMap swigmap = (VectMap) runInstance.getVal();
665
666 ArrayList<HashMap<String, String>> nativemap = HistoryHandler.convertSwigToNative(swigmap);
667
668 return nativemap;
669 }
alision7f18fc82013-05-01 09:37:33 -0400670
alision43a9b362013-05-01 16:30:15 -0400671 /*************************
672 * Transfer related API
673 *************************/
674
alision7f18fc82013-05-01 09:37:33 -0400675 @Override
676 public void transfer(final String callID, final String to) throws RemoteException {
677 getExecutor().execute(new SipRunnable() {
678 @Override
679 protected void doRun() throws SameThreadException, RemoteException {
680 Log.i(TAG, "SipService.transfer() thread running...");
681 if (callManagerJNI.transfer(callID, to)) {
682 Bundle bundle = new Bundle();
683 bundle.putString("CallID", callID);
684 bundle.putString("State", "HUNGUP");
685 Intent intent = new Intent(CallManagerCallBack.CALL_STATE_CHANGED);
alision7f18fc82013-05-01 09:37:33 -0400686 intent.putExtra("com.savoirfairelinux.sflphone.service.newstate", bundle);
alision84813a12013-05-27 17:40:39 -0400687 sendBroadcast(intent);
alision7f18fc82013-05-01 09:37:33 -0400688 } else
689 Log.i(TAG, "NOT OK");
690 }
691 });
692
693 }
alision43a9b362013-05-01 16:30:15 -0400694
alision7f18fc82013-05-01 09:37:33 -0400695 @Override
696 public void attendedTransfer(final String transferID, final String targetID) throws RemoteException {
697 getExecutor().execute(new SipRunnable() {
698 @Override
699 protected void doRun() throws SameThreadException, RemoteException {
alision43a9b362013-05-01 16:30:15 -0400700 Log.i(TAG, "SipService.attendedTransfer() thread running...");
alision7f18fc82013-05-01 09:37:33 -0400701 if (callManagerJNI.attendedTransfer(transferID, targetID)) {
702 Log.i(TAG, "OK");
alision7f18fc82013-05-01 09:37:33 -0400703 } else
704 Log.i(TAG, "NOT OK");
705 }
706 });
alision43a9b362013-05-01 16:30:15 -0400707
708 }
709
710 /*************************
711 * Conference related API
712 *************************/
713
714 @Override
715 public void removeConference(final String confID) throws RemoteException {
716 getExecutor().execute(new SipRunnable() {
717 @Override
718 protected void doRun() throws SameThreadException, RemoteException {
719 Log.i(TAG, "SipService.createConference() thread running...");
720 callManagerJNI.removeConference(confID);
721 }
722 });
723
alision7f18fc82013-05-01 09:37:33 -0400724 }
725
726 @Override
alision43a9b362013-05-01 16:30:15 -0400727 public void joinParticipant(final String sel_callID, final String drag_callID) throws RemoteException {
728 getExecutor().execute(new SipRunnable() {
729 @Override
730 protected void doRun() throws SameThreadException, RemoteException {
731 Log.i(TAG, "SipService.joinParticipant() thread running...");
732 callManagerJNI.joinParticipant(sel_callID, drag_callID);
alision806e18e2013-06-21 15:30:17 -0400733 // Generate a CONF_CREATED callback
alision43a9b362013-05-01 16:30:15 -0400734 }
735 });
736
alision7f18fc82013-05-01 09:37:33 -0400737 }
738
alision7f18fc82013-05-01 09:37:33 -0400739 @Override
alision806e18e2013-06-21 15:30:17 -0400740 public void addParticipant(final SipCall call, final String confID) throws RemoteException {
alision43a9b362013-05-01 16:30:15 -0400741 getExecutor().execute(new SipRunnable() {
742 @Override
743 protected void doRun() throws SameThreadException, RemoteException {
744 Log.i(TAG, "SipService.addParticipant() thread running...");
alision806e18e2013-06-21 15:30:17 -0400745 callManagerJNI.addParticipant(call.getCallId(), confID);
746 current_confs.get(confID).getParticipants().add(call);
alision43a9b362013-05-01 16:30:15 -0400747 }
748 });
749
alision7f18fc82013-05-01 09:37:33 -0400750 }
751
752 @Override
alision43a9b362013-05-01 16:30:15 -0400753 public void addMainParticipant(final String confID) throws RemoteException {
754 getExecutor().execute(new SipRunnable() {
755 @Override
756 protected void doRun() throws SameThreadException, RemoteException {
757 Log.i(TAG, "SipService.addMainParticipant() thread running...");
758 callManagerJNI.addMainParticipant(confID);
759 }
760 });
761
alision7f18fc82013-05-01 09:37:33 -0400762 }
763
764 @Override
alision43a9b362013-05-01 16:30:15 -0400765 public void detachParticipant(final String callID) throws RemoteException {
766 getExecutor().execute(new SipRunnable() {
767 @Override
768 protected void doRun() throws SameThreadException, RemoteException {
769 Log.i(TAG, "SipService.detachParticipant() thread running...");
alision806e18e2013-06-21 15:30:17 -0400770 Log.i(TAG, "Detaching " + callID);
771 Iterator<Entry<String, Conference>> it = current_confs.entrySet().iterator();
772 Log.i(TAG, "current_confs size " + current_confs.size());
773 while (it.hasNext()) {
774 Conference tmp = it.next().getValue();
775 Log.i(TAG, "conf has " + tmp.getParticipants().size() + " participants");
776 if (tmp.contains(callID)) {
777 current_calls.put(callID, tmp.getCall(callID));
778 Log.i(TAG, "Call found and put in current_calls");
779 }
780 }
alision43a9b362013-05-01 16:30:15 -0400781 callManagerJNI.detachParticipant(callID);
782 }
783 });
784
alision7f18fc82013-05-01 09:37:33 -0400785 }
786
787 @Override
alision43a9b362013-05-01 16:30:15 -0400788 public void joinConference(final String sel_confID, final String drag_confID) throws RemoteException {
789 getExecutor().execute(new SipRunnable() {
790 @Override
791 protected void doRun() throws SameThreadException, RemoteException {
792 Log.i(TAG, "SipService.joinConference() thread running...");
793 callManagerJNI.joinConference(sel_confID, drag_confID);
794 }
795 });
796
alision7f18fc82013-05-01 09:37:33 -0400797 }
798
799 @Override
alision43a9b362013-05-01 16:30:15 -0400800 public void hangUpConference(final String confID) throws RemoteException {
801 getExecutor().execute(new SipRunnable() {
802 @Override
803 protected void doRun() throws SameThreadException, RemoteException {
804 Log.i(TAG, "SipService.joinConference() thread running...");
805 callManagerJNI.hangUpConference(confID);
806 }
807 });
808
alision7f18fc82013-05-01 09:37:33 -0400809 }
810
811 @Override
alision43a9b362013-05-01 16:30:15 -0400812 public void holdConference(final String confID) throws RemoteException {
813 getExecutor().execute(new SipRunnable() {
814 @Override
815 protected void doRun() throws SameThreadException, RemoteException {
816 Log.i(TAG, "SipService.holdConference() thread running...");
817 callManagerJNI.holdConference(confID);
818 }
819 });
820
alision7f18fc82013-05-01 09:37:33 -0400821 }
822
823 @Override
alision43a9b362013-05-01 16:30:15 -0400824 public void unholdConference(final String confID) throws RemoteException {
825 getExecutor().execute(new SipRunnable() {
826 @Override
827 protected void doRun() throws SameThreadException, RemoteException {
828 Log.i(TAG, "SipService.unholdConference() thread running...");
829 callManagerJNI.unholdConference(confID);
830 }
831 });
832
alision7f18fc82013-05-01 09:37:33 -0400833 }
Alexandre Lision67817192013-07-18 12:04:30 -0400834
alisioncd8fb912013-06-28 14:43:51 -0400835 @Override
836 public boolean isConferenceParticipant(final String callID) throws RemoteException {
837 class IsParticipant extends SipRunnableWithReturn {
838
839 @Override
840 protected Boolean doRun() throws SameThreadException {
841 Log.i(TAG, "SipService.isRecording() thread running...");
842 return callManagerJNI.isConferenceParticipant(callID);
843 }
844 }
845
846 IsParticipant runInstance = new IsParticipant();
847 getExecutor().execute(runInstance);
848 while (!runInstance.isDone()) {
849 }
850
851 return (Boolean) runInstance.getVal();
852 }
alision7f18fc82013-05-01 09:37:33 -0400853
854 @Override
alisiondf1dac92013-06-27 17:35:53 -0400855 public HashMap<String, Conference> getConferenceList() throws RemoteException {
Alexandre Lision67817192013-07-18 12:04:30 -0400856 // class ConfList extends SipRunnableWithReturn {
857 // @Override
858 // protected StringVect doRun() throws SameThreadException {
859 // Log.i(TAG, "SipService.getConferenceList() thread running...");
860 // return callManagerJNI.getConferenceList();
861 // }
862 // }
863 // ;
864 // ConfList runInstance = new ConfList();
865 // getExecutor().execute(runInstance);
866 // while (!runInstance.isDone()) {
867 // // Log.w(TAG, "Waiting for getConferenceList");
868 // }
869 // StringVect swigvect = (StringVect) runInstance.getVal();
870 //
871 // ArrayList<String> nativelist = new ArrayList<String>();
872 //
873 // for (int i = 0; i < swigvect.size(); i++)
874 // nativelist.add(swigvect.get(i));
875 //
876 // return nativelist;
alisiondf1dac92013-06-27 17:35:53 -0400877 return current_confs;
alision7f18fc82013-05-01 09:37:33 -0400878 }
879
880 @Override
alision907bde72013-06-20 14:40:37 -0400881 public List getParticipantList(final String confID) throws RemoteException {
882 class PartList extends SipRunnableWithReturn {
883 @Override
884 protected StringVect doRun() throws SameThreadException {
885 Log.i(TAG, "SipService.getAccountList() thread running...");
886 return callManagerJNI.getParticipantList(confID);
887 }
888 }
889 ;
890 PartList runInstance = new PartList();
891 getExecutor().execute(runInstance);
892 while (!runInstance.isDone()) {
893 // Log.w(TAG, "Waiting for getConferenceList");
894 }
895 StringVect swigvect = (StringVect) runInstance.getVal();
896
897 ArrayList<String> nativelist = new ArrayList<String>();
898
899 for (int i = 0; i < swigvect.size(); i++)
900 nativelist.add(swigvect.get(i));
901
902 return nativelist;
alision7f18fc82013-05-01 09:37:33 -0400903 }
alision806e18e2013-06-21 15:30:17 -0400904
alision1005ba12013-06-19 13:52:44 -0400905 @Override
alision7f18fc82013-05-01 09:37:33 -0400906 public String getConferenceId(String callID) throws RemoteException {
alision43a9b362013-05-01 16:30:15 -0400907 Log.e(TAG, "getConferenceList not implemented");
alision7f18fc82013-05-01 09:37:33 -0400908 return null;
909 }
910
911 @Override
alision806e18e2013-06-21 15:30:17 -0400912 public String getConferenceDetails(final String callID) throws RemoteException {
913 class ConfDetails extends SipRunnableWithReturn {
914 @Override
915 protected StringMap doRun() throws SameThreadException {
916 Log.i(TAG, "SipService.getAccountList() thread running...");
917 return callManagerJNI.getConferenceDetails(callID);
918 }
919 }
920 ;
921 ConfDetails runInstance = new ConfDetails();
922 getExecutor().execute(runInstance);
923 while (!runInstance.isDone()) {
924 // Log.w(TAG, "Waiting for getConferenceList");
925 }
926 StringMap swigvect = (StringMap) runInstance.getVal();
927
928 return swigvect.get("CONF_STATE");
alision7f18fc82013-05-01 09:37:33 -0400929 }
930
alision04a00182013-05-10 17:05:29 -0400931 @Override
932 public String getRecordPath() throws RemoteException {
933 class RecordPath extends SipRunnableWithReturn {
934
935 @Override
936 protected String doRun() throws SameThreadException {
937 Log.i(TAG, "SipService.getRecordPath() thread running...");
Adrien Béraud9360f242013-09-19 11:07:42 +1000938 return configurationManagerJNI.getRecordPath();
alision04a00182013-05-10 17:05:29 -0400939 }
940 }
941
942 RecordPath runInstance = new RecordPath();
943 getExecutor().execute(runInstance);
944 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400945 // Log.w(TAG, "Waiting for getRecordPath");
alision04a00182013-05-10 17:05:29 -0400946 }
947 String path = (String) runInstance.getVal();
948
949 return path;
950 }
951
952 @Override
Alexandre Lisiona764c682013-09-09 10:02:07 -0400953 public boolean toggleRecordingCall(final String id) throws RemoteException {
Adrien Béraud9360f242013-09-19 11:07:42 +1000954
Alexandre Lisiona764c682013-09-09 10:02:07 -0400955 class ToggleRecording extends SipRunnableWithReturn {
956
alision04a00182013-05-10 17:05:29 -0400957 @Override
Alexandre Lisiona764c682013-09-09 10:02:07 -0400958 protected Boolean doRun() throws SameThreadException {
959 Log.i(TAG, "SipService.toggleRecordingCall() thread running...");
960 return callManagerJNI.toggleRecording(id);
alision04a00182013-05-10 17:05:29 -0400961 }
Alexandre Lisiona764c682013-09-09 10:02:07 -0400962 }
963
964 ToggleRecording runInstance = new ToggleRecording();
965 getExecutor().execute(runInstance);
966 while (!runInstance.isDone()) {
967 }
968
969 return (Boolean) runInstance.getVal();
alision04a00182013-05-10 17:05:29 -0400970
971 }
Alexandre Lision67817192013-07-18 12:04:30 -0400972
alision50fa0722013-06-25 17:29:44 -0400973 @Override
alisiondf1dac92013-06-27 17:35:53 -0400974 public boolean isRecording(final String id) throws RemoteException {
975 class IsRecording extends SipRunnableWithReturn {
976
977 @Override
978 protected Boolean doRun() throws SameThreadException {
979 Log.i(TAG, "SipService.isRecording() thread running...");
980 return callManagerJNI.getIsRecording(id);
981 }
982 }
983
984 IsRecording runInstance = new IsRecording();
985 getExecutor().execute(runInstance);
986 while (!runInstance.isDone()) {
987 }
988
989 return (Boolean) runInstance.getVal();
Alexandre Lision67817192013-07-18 12:04:30 -0400990
alisiondf1dac92013-06-27 17:35:53 -0400991 }
Alexandre Lision67817192013-07-18 12:04:30 -0400992
alisiondf1dac92013-06-27 17:35:53 -0400993 @Override
alision50fa0722013-06-25 17:29:44 -0400994 public boolean startRecordedFilePlayback(final String filepath) throws RemoteException {
995 getExecutor().execute(new SipRunnable() {
996 @Override
997 protected void doRun() throws SameThreadException, RemoteException {
998 Log.i(TAG, "SipService.setRecordingCall() thread running...");
999 callManagerJNI.startRecordedFilePlayback(filepath);
1000 }
1001 });
1002 return false;
1003 }
1004
1005 @Override
1006 public void stopRecordedFilePlayback(final String filepath) throws RemoteException {
1007 getExecutor().execute(new SipRunnable() {
1008 @Override
1009 protected void doRun() throws SameThreadException, RemoteException {
1010 Log.i(TAG, "SipService.stopRecordedFilePlayback() thread running...");
1011 callManagerJNI.stopRecordedFilePlayback(filepath);
1012 }
1013 });
1014 }
alision04a00182013-05-10 17:05:29 -04001015
1016 @Override
1017 public void setRecordPath(final String path) throws RemoteException {
1018 getExecutor().execute(new SipRunnable() {
1019 @Override
1020 protected void doRun() throws SameThreadException, RemoteException {
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001021 Log.i(TAG, "SipService.setRecordPath() " + path + " thread running...");
Adrien Béraud9360f242013-09-19 11:07:42 +10001022 configurationManagerJNI.setRecordPath(path);
alision04a00182013-05-10 17:05:29 -04001023 }
1024 });
1025 }
1026
1027 @Override
1028 public void sendTextMessage(final String callID, final String message, final String from) throws RemoteException {
1029 getExecutor().execute(new SipRunnable() {
1030 @Override
1031 protected void doRun() throws SameThreadException, RemoteException {
1032 Log.i(TAG, "SipService.sendTextMessage() thread running...");
Alexandre Lision10314352013-07-17 15:06:56 -04001033 callManagerJNI.sendTextMessage(callID, message);
alision04a00182013-05-10 17:05:29 -04001034 }
1035 });
1036
1037 }
1038
alisiond295ec22013-05-17 10:12:13 -04001039 @Override
Alexandre Lision4cf78702013-10-16 13:43:23 -04001040 public List getAudioCodecList(final String accountID) throws RemoteException {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001041 class AudioCodecList extends SipRunnableWithReturn {
1042
1043 @Override
Alexandre Lision933ef0a2013-10-15 17:28:40 -04001044 protected ArrayList<Codec> doRun() throws SameThreadException {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001045 Log.i(TAG, "SipService.getAudioCodecList() thread running...");
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001046 ArrayList<Codec> results = new ArrayList<Codec>();
Alexandre Lision4cf78702013-10-16 13:43:23 -04001047
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001048 IntVect active_payloads = configurationManagerJNI.getActiveAudioCodecList(accountID);
1049 for (int i = 0; i < active_payloads.size(); ++i) {
1050
Alexandre Lision039a3cf2013-10-16 17:44:57 -04001051 results.add(new Codec(active_payloads.get(i), configurationManagerJNI.getAudioCodecDetails(active_payloads.get(i)), true));
1052
1053 if (results.get(i).getName().length() == 0)
1054 results.remove(i);
Alexandre Lision4cf78702013-10-16 13:43:23 -04001055 }
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001056
Alexandre Lision039a3cf2013-10-16 17:44:57 -04001057 // if (results.get(active_payloads.get(i)) != null) {
1058 // results.get(active_payloads.get(i)).setEnabled(true);
1059
1060 IntVect payloads = configurationManagerJNI.getAudioCodecList();
1061
1062 for (int i = 0; i < payloads.size(); ++i) {
1063 boolean isActive = false;
1064 for (Codec co : results) {
1065 if (co.getPayload().toString().contentEquals(String.valueOf(payloads.get(i))))
1066 isActive = true;
1067
1068 }
1069 if (isActive)
1070 continue;
1071 else
1072 results.add(new Codec(payloads.get(i), configurationManagerJNI.getAudioCodecDetails(payloads.get(i)), false));
1073
1074 }
1075
1076 // if (!results.containsKey(payloads.get(i))) {
1077 // results.put(payloads.get(i), new Codec(payloads.get(i), configurationManagerJNI.getAudioCodecDetails(payloads.get(i)), false));
1078 // Log.i(TAG, "Other, Adding:" + results.get((payloads.get(i))).getName());
1079 // }
1080
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001081 return results;
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001082 }
1083 }
1084
1085 AudioCodecList runInstance = new AudioCodecList();
1086 getExecutor().execute(runInstance);
1087 while (!runInstance.isDone()) {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001088 }
Alexandre Lision933ef0a2013-10-15 17:28:40 -04001089 ArrayList<Codec> codecs = (ArrayList<Codec>) runInstance.getVal();
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001090 return codecs;
alisiond295ec22013-05-17 10:12:13 -04001091 }
1092
alision9f7a6ec2013-05-24 16:26:26 -04001093 @Override
Alexandre Lision4cf78702013-10-16 13:43:23 -04001094 public Map getRingtoneList() throws RemoteException {
1095 class RingtoneList extends SipRunnableWithReturn {
1096
1097 @Override
1098 protected StringMap doRun() throws SameThreadException {
1099 Log.i(TAG, "SipService.getRingtoneList() thread running...");
1100 return configurationManagerJNI.getRingtoneList();
1101 }
1102 }
1103
1104 RingtoneList runInstance = new RingtoneList();
1105 getExecutor().execute(runInstance);
1106 while (!runInstance.isDone()) {
1107 }
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001108 StringMap ringtones = (StringMap) runInstance.getVal();
1109
1110 for (int i = 0; i < ringtones.size(); ++i) {
1111 // Log.i(TAG,"ringtones "+i+" "+ ringtones.);
1112 }
1113
Alexandre Lision4cf78702013-10-16 13:43:23 -04001114 return null;
1115 }
1116
1117 @Override
1118 public void setActiveCodecList(final List codecs, final String accountID) throws RemoteException {
1119 getExecutor().execute(new SipRunnable() {
1120 @Override
1121 protected void doRun() throws SameThreadException, RemoteException {
1122 Log.i(TAG, "SipService.setActiveAudioCodecList() thread running...");
1123 StringVect list = new StringVect();
1124 for (int i = 0; i < codecs.size(); ++i) {
1125 list.add((String) codecs.get(i));
1126 }
1127 configurationManagerJNI.setActiveAudioCodecList(list, accountID);
1128 }
1129 });
1130 }
1131
1132 @Override
alisionfde875f2013-05-28 17:01:54 -04001133 public HashMap<String, SipCall> getCallList() throws RemoteException {
alision85704182013-05-29 15:23:03 -04001134 // class CallList extends SipRunnableWithReturn {
1135 //
1136 // @Override
1137 // protected StringVect doRun() throws SameThreadException {
1138 // Log.i(TAG, "SipService.getCallList() thread running...");
1139 // return callManagerJNI.getCallList();
1140 // }
1141 // }
1142 //
1143 // CallList runInstance = new CallList();
1144 // getExecutor().execute(runInstance);
1145 // while (!runInstance.isDone()) {
1146 // Log.w(TAG, "Waiting for getAudioCodecList");
1147 // }
1148 // StringVect swigmap = (StringVect) runInstance.getVal();
1149 //
1150 // ArrayList<String> nativemap = new ArrayList<String>();
1151 // for (int i = 0; i < swigmap.size(); ++i) {
1152 //
1153 // String t = swigmap.get(i);
1154 // nativemap.add(t);
1155 // }
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001156 // if(callManagerJNI == null)
1157 // return new HashMap<String, SipCall>();
1158 //
1159 //
1160 // HashMap<String, SipCall> results = new HashMap<String, SipCall>();
1161 // StringVect calls = callManagerJNI.getCallList();
1162 // for(int i = 0 ; i < calls.size(); ++i){
1163 // results.put(calls.get(i), new SipCall(calls.get(i), callManagerJNI.getCallDetails(calls.get(i))));
1164 // }
alision9f7a6ec2013-05-24 16:26:26 -04001165
alision2cb99562013-05-30 17:02:20 -04001166 return getCurrent_calls();
alision9f7a6ec2013-05-24 16:26:26 -04001167 }
1168
alision85704182013-05-29 15:23:03 -04001169 @Override
1170 public SipCall getCall(String callID) throws RemoteException {
alision2cb99562013-05-30 17:02:20 -04001171 return getCurrent_calls().get(callID);
1172 }
1173
1174 /***********************
1175 * Notification API
1176 ***********************/
1177 @Override
1178 public void createNotification() throws RemoteException {
1179 makeNotification();
alisioncc7bb422013-06-06 15:31:39 -04001180
alision2cb99562013-05-30 17:02:20 -04001181 }
1182
1183 @Override
1184 public void destroyNotification() throws RemoteException {
1185 removeNotification();
alisioncc7bb422013-06-06 15:31:39 -04001186
alision2cb99562013-05-30 17:02:20 -04001187 }
alisioncc7bb422013-06-06 15:31:39 -04001188
Adrien Béraud9360f242013-09-19 11:07:42 +10001189 private final int NOTIFICATION_ID = new Random().nextInt(1000);
alisioncc7bb422013-06-06 15:31:39 -04001190
alision2cb99562013-05-30 17:02:20 -04001191 private void makeNotification() {
alisioncc7bb422013-06-06 15:31:39 -04001192 if (current_calls.size() == 0) {
alision2cb99562013-05-30 17:02:20 -04001193 return;
1194 }
1195 Intent notificationIntent = new Intent(getApplicationContext(), SFLPhoneHomeActivity.class);
alisioncc7bb422013-06-06 15:31:39 -04001196 PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 007, notificationIntent,
1197 PendingIntent.FLAG_UPDATE_CURRENT);
alision2cb99562013-05-30 17:02:20 -04001198
1199 NotificationManager nm = (NotificationManager) getBaseContext().getSystemService(Context.NOTIFICATION_SERVICE);
Adrien Béraud9360f242013-09-19 11:07:42 +10001200 nm.cancel(NOTIFICATION_ID); // clear previous notifications.
alision2cb99562013-05-30 17:02:20 -04001201
1202 NotificationCompat.Builder builder = new NotificationCompat.Builder(getBaseContext());
alisioncc7bb422013-06-06 15:31:39 -04001203 //
1204 // builder.setContent(view);
1205 builder.setContentIntent(contentIntent).setOngoing(true).setSmallIcon(R.drawable.ic_launcher)
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001206 .setContentTitle(getCurrent_calls().size() + " ongoing calls").setTicker("Pending calls").setWhen(System.currentTimeMillis())
1207 .setAutoCancel(false);
alision2cb99562013-05-30 17:02:20 -04001208 builder.setPriority(NotificationCompat.PRIORITY_MAX);
1209 Notification n = builder.build();
1210
1211 nm.notify(NOTIFICATION_ID, n);
alision2cb99562013-05-30 17:02:20 -04001212 }
1213
1214 public void removeNotification() {
1215 NotificationManager nm = (NotificationManager) getBaseContext().getSystemService(Context.NOTIFICATION_SERVICE);
1216 nm.cancel(NOTIFICATION_ID);
alision85704182013-05-29 15:23:03 -04001217 }
1218
alisiondf1dac92013-06-27 17:35:53 -04001219 @Override
1220 public Conference getCurrentCall() throws RemoteException {
Alexandre Lision67817192013-07-18 12:04:30 -04001221 for (SipCall i : current_calls.values()) {
Adrien Béraud9360f242013-09-19 11:07:42 +10001222
Alexandre Lisionc51ccb12013-09-11 16:00:30 -04001223 // Incoming >> Ongoing
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001224 if (i.isIncoming()) {
Alexandre Lisionc51ccb12013-09-11 16:00:30 -04001225 Conference tmp = new Conference("-1");
1226 tmp.getParticipants().add(i);
1227 return tmp;
1228 }
Adrien Béraud9360f242013-09-19 11:07:42 +10001229
Alexandre Lision67817192013-07-18 12:04:30 -04001230 if (i.isOngoing()) {
alisiondf1dac92013-06-27 17:35:53 -04001231 Conference tmp = new Conference("-1");
1232 tmp.getParticipants().add(i);
1233 return tmp;
1234 }
1235 }
Alexandre Lision67817192013-07-18 12:04:30 -04001236
1237 if (!current_confs.isEmpty()) {
alisiondf1dac92013-06-27 17:35:53 -04001238 return (Conference) current_confs.values().toArray()[0];
1239 }
1240 return null;
1241 }
1242
Alexandre Lision64dc8c02013-09-25 15:32:25 -04001243 @Override
1244 public void playDtmf(final String key) throws RemoteException {
1245 getExecutor().execute(new SipRunnable() {
1246 @Override
1247 protected void doRun() throws SameThreadException, RemoteException {
1248 Log.i(TAG, "SipService.playDtmf() thread running...");
1249 callManagerJNI.playDTMF(key);
1250 }
1251 });
1252 }
1253
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001254 @Override
1255 public List getConcurrentCalls() throws RemoteException {
1256 ArrayList<Conference> toReturn = new ArrayList<Conference>();
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001257
1258 for (SipCall sip : current_calls.values()) {
1259 if (!sip.isCurrent()) {
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001260 Conference tmp = new Conference("-1");
1261 tmp.getParticipants().add(sip);
1262 toReturn.add(tmp);
1263 }
1264 }
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001265
1266 Log.i(TAG, "toReturn SIZE " + toReturn.size());
1267
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001268 return toReturn;
1269 }
1270
Emeric Vigier6119d782012-09-21 18:04:14 -04001271 };
Emeric Vigiereaf2c492012-09-19 14:38:20 -04001272}