blob: 7d8eb66f9b1278f479eb6f3c8745ef3650121be7 [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;
Alexandre Lision6d867b92013-10-25 15:36:28 -040046import org.sflphone.utils.MediaManager;
Alexandre Lisione0045442013-10-25 09:16:19 -040047import org.sflphone.utils.SipNotifications;
Alexandre Lision064e1e02013-10-01 16:18:42 -040048
alision2cb99562013-05-30 17:02:20 -040049import android.app.Notification;
50import android.app.NotificationManager;
51import android.app.PendingIntent;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040052import android.app.Service;
alision17052d42013-04-22 10:39:38 -040053import android.content.Context;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040054import android.content.Intent;
alision17052d42013-04-22 10:39:38 -040055import android.content.IntentFilter;
alision7f18fc82013-05-01 09:37:33 -040056import android.os.Bundle;
Emeric Vigier6119d782012-09-21 18:04:14 -040057import android.os.Handler;
58import android.os.HandlerThread;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040059import android.os.IBinder;
Emeric Vigier6119d782012-09-21 18:04:14 -040060import android.os.Looper;
61import android.os.Message;
alision5f899632013-04-22 17:26:56 -040062import android.os.RemoteException;
alision2cb99562013-05-30 17:02:20 -040063import android.support.v4.app.NotificationCompat;
alision17052d42013-04-22 10:39:38 -040064import android.support.v4.content.LocalBroadcastManager;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040065import android.util.Log;
Alexandre Lisionafbe8f62013-10-25 15:52:44 -040066import android.widget.Toast;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040067
Emeric Vigiereaf2c492012-09-19 14:38:20 -040068public class SipService extends Service {
69
70 static final String TAG = "SipService";
71 static final int DELAY = 5000; /* 5 sec */
Emeric Vigier6119d782012-09-21 18:04:14 -040072 private SipServiceExecutor mExecutor;
73 private static HandlerThread executorThread;
alision3ea8f3c2013-07-16 17:35:35 -040074 private CallManager callManagerJNI;
Alexandre Lision67817192013-07-18 12:04:30 -040075 private ManagerImpl managerImpl;
Emeric Vigier0007dee2012-09-24 11:35:58 -040076 private CallManagerCallBack callManagerCallBack;
alision3ea8f3c2013-07-16 17:35:35 -040077 private ConfigurationManager configurationManagerJNI;
Alexandre Savardfccd1dc2012-10-17 17:31:38 -040078 private ConfigurationManagerCallback configurationManagerCallback;
Emeric Vigier6119d782012-09-21 18:04:14 -040079 private boolean isPjSipStackStarted = false;
alisioncc7bb422013-06-06 15:31:39 -040080
Alexandre Lisione0045442013-10-25 09:16:19 -040081 public SipNotifications notificationManager;
Alexandre Lision6d867b92013-10-25 15:36:28 -040082 public MediaManager mediaManager;
Alexandre Lisione0045442013-10-25 09:16:19 -040083
alision2cb99562013-05-30 17:02:20 -040084 private HashMap<String, SipCall> current_calls = new HashMap<String, SipCall>();
alision806e18e2013-06-21 15:30:17 -040085 private HashMap<String, Conference> current_confs = new HashMap<String, Conference>();
86 private IncomingReceiver receiver;
Emeric Vigier6119d782012-09-21 18:04:14 -040087
alision806e18e2013-06-21 15:30:17 -040088 public HashMap<String, Conference> getCurrent_confs() {
89 return current_confs;
90 }
alision43a9b362013-05-01 16:30:15 -040091
92 @Override
93 public boolean onUnbind(Intent i) {
94 super.onUnbind(i);
95 Log.i(TAG, "onUnbind(intent)");
Alexandre Lision0f550ee2013-10-25 15:34:38 -040096 return true;
97 }
Alexandre Lisiondd68f652013-10-28 11:00:12 -040098
Alexandre Lision0f550ee2013-10-25 15:34:38 -040099 @Override
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400100 public void onRebind(Intent i) {
Alexandre Lision0f550ee2013-10-25 15:34:38 -0400101 super.onRebind(i);
alision43a9b362013-05-01 16:30:15 -0400102 }
103
104 /* called once by startService() */
105 @Override
106 public void onCreate() {
107 Log.i(TAG, "onCreated");
108 super.onCreate();
109
alision43a9b362013-05-01 16:30:15 -0400110 IntentFilter callFilter = new IntentFilter(CallManagerCallBack.CALL_STATE_CHANGED);
111 callFilter.addAction(CallManagerCallBack.INCOMING_CALL);
112 callFilter.addAction(CallManagerCallBack.NEW_CALL_CREATED);
alision4a0eb092013-05-07 13:52:03 -0400113 callFilter.addAction(ConfigurationManagerCallback.ACCOUNT_STATE_CHANGED);
114 callFilter.addAction(ConfigurationManagerCallback.ACCOUNTS_CHANGED);
alision04a00182013-05-10 17:05:29 -0400115 callFilter.addAction(CallManagerCallBack.INCOMING_TEXT);
alision806e18e2013-06-21 15:30:17 -0400116 callFilter.addAction(CallManagerCallBack.CONF_CREATED);
117 callFilter.addAction(CallManagerCallBack.CONF_REMOVED);
118 callFilter.addAction(CallManagerCallBack.CONF_CHANGED);
alisiondf1dac92013-06-27 17:35:53 -0400119 callFilter.addAction(CallManagerCallBack.RECORD_STATE_CHANGED);
alision806e18e2013-06-21 15:30:17 -0400120 receiver = new IncomingReceiver(this, mBinder);
alision2cb99562013-05-30 17:02:20 -0400121 LocalBroadcastManager.getInstance(this).registerReceiver(receiver, callFilter);
alision2cb99562013-05-30 17:02:20 -0400122
alisioncc7bb422013-06-06 15:31:39 -0400123 getExecutor().execute(new StartRunnable());
Alexandre Lisione0045442013-10-25 09:16:19 -0400124
125 notificationManager = new SipNotifications(this);
Alexandre Lision6d867b92013-10-25 15:36:28 -0400126 mediaManager = new MediaManager(this);
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400127
Alexandre Lisione0045442013-10-25 09:16:19 -0400128 notificationManager.onServiceCreate();
Alexandre Lision6d867b92013-10-25 15:36:28 -0400129 mediaManager.startService();
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400130
alisioncc7bb422013-06-06 15:31:39 -0400131 }
alision43a9b362013-05-01 16:30:15 -0400132
133 /* called for each startService() */
134 @Override
135 public int onStartCommand(Intent intent, int flags, int startId) {
136 Log.i(TAG, "onStarted");
137 super.onStartCommand(intent, flags, startId);
138
alision806e18e2013-06-21 15:30:17 -0400139 receiver = new IncomingReceiver(this, mBinder);
Alexandre Lisione0045442013-10-25 09:16:19 -0400140
Alexandre Lision0f550ee2013-10-25 15:34:38 -0400141 return START_STICKY; /* started and stopped explicitly */
alision43a9b362013-05-01 16:30:15 -0400142 }
143
144 @Override
145 public void onDestroy() {
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400146 Log.i(TAG, "onDestroyed");
alision43a9b362013-05-01 16:30:15 -0400147 /* called once by stopService() */
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400148
Alexandre Lision0a300ff2013-09-23 14:22:34 -0400149 LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
Alexandre Lisione0045442013-10-25 09:16:19 -0400150 notificationManager.onServiceDestroy();
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400151 // sflphoneApp.setServiceRunning(false);
Alexandre Lisionef2aa9e2013-10-25 16:22:52 -0400152
Alexandre Lisionafbe8f62013-10-25 15:52:44 -0400153
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400154 getExecutor().execute(new FinalizeRunnable());
alision43a9b362013-05-01 16:30:15 -0400155 super.onDestroy();
156
alision43a9b362013-05-01 16:30:15 -0400157 }
158
159 @Override
160 public IBinder onBind(Intent arg0) {
161 Log.i(TAG, "onBound");
162 return mBinder;
163 }
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400164
alision43a9b362013-05-01 16:30:15 -0400165 private static Looper createLooper() {
166 if (executorThread == null) {
167 Log.d(TAG, "Creating new handler thread");
168 // ADT gives a fake warning due to bad parse rule.
169 executorThread = new HandlerThread("SipService.Executor");
170 executorThread.start();
171 }
172 return executorThread.getLooper();
173 }
174
175 public SipServiceExecutor getExecutor() {
176 // create mExecutor lazily
177 if (mExecutor == null) {
178 mExecutor = new SipServiceExecutor(this);
179 }
180 return mExecutor;
181 }
182
183 // Executes immediate tasks in a single executorThread.
184 public static class SipServiceExecutor extends Handler {
185 WeakReference<SipService> handlerService;
186
187 SipServiceExecutor(SipService s) {
188 super(createLooper());
189 handlerService = new WeakReference<SipService>(s);
190 }
191
192 public void execute(Runnable task) {
193 // TODO: add wakelock
194 Message.obtain(this, 0/* don't care */, task).sendToTarget();
Alexandre Lisioncdec5952013-07-17 14:18:22 -0400195 Log.w(TAG, "SenT!");
alision43a9b362013-05-01 16:30:15 -0400196 }
197
198 @Override
199 public void handleMessage(Message msg) {
200 if (msg.obj instanceof Runnable) {
201 executeInternal((Runnable) msg.obj);
202 } else {
203 Log.w(TAG, "can't handle msg: " + msg);
204 }
205 }
206
207 private void executeInternal(Runnable task) {
208 try {
209 task.run();
210 } catch (Throwable t) {
211 Log.e(TAG, "run task: " + task, t);
212 }
213 }
214 }
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400215
216 private void stopDaemon(){
217 if(managerImpl != null){
218 managerImpl.finish();
219 isPjSipStackStarted = false;
220 }
221 }
alision43a9b362013-05-01 16:30:15 -0400222
223 private void startPjSipStack() throws SameThreadException {
224 if (isPjSipStackStarted)
225 return;
226
227 try {
228 System.loadLibrary("gnustl_shared");
229 System.loadLibrary("expat");
230 System.loadLibrary("yaml");
231 System.loadLibrary("ccgnu2");
232 System.loadLibrary("crypto");
233 System.loadLibrary("ssl");
Alexandre Lision7c6f4a62013-09-05 13:27:01 -0400234 System.loadLibrary("sndfile");
alision43a9b362013-05-01 16:30:15 -0400235 System.loadLibrary("ccrtp1");
alision43a9b362013-05-01 16:30:15 -0400236 System.loadLibrary("samplerate");
237 System.loadLibrary("codec_ulaw");
238 System.loadLibrary("codec_alaw");
Alexandre Lision0a300ff2013-09-23 14:22:34 -0400239 System.loadLibrary("codec_g722");
Alexandre Lision6deda412013-09-25 13:21:22 -0400240 System.loadLibrary("codec_opus");
Alexandre Lisiona1ad1c32013-10-15 16:35:20 -0400241 System.loadLibrary("codec_gsm");
Alexandre Lision62138172013-10-17 11:52:45 -0400242 System.loadLibrary("codec_speex_nb");
243 System.loadLibrary("codec_speex_ub");
244 System.loadLibrary("codec_speex_wb");
alision43a9b362013-05-01 16:30:15 -0400245 System.loadLibrary("speexresampler");
246 System.loadLibrary("sflphone");
247 isPjSipStackStarted = true;
Adrien Béraud9360f242013-09-19 11:07:42 +1000248
alision43a9b362013-05-01 16:30:15 -0400249 } catch (UnsatisfiedLinkError e) {
250 Log.e(TAG, "Problem with the current Pj stack...", e);
251 isPjSipStackStarted = false;
252 return;
253 } catch (Exception e) {
254 Log.e(TAG, "Problem with the current Pj stack...", e);
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400255 isPjSipStackStarted = false;
alision43a9b362013-05-01 16:30:15 -0400256 }
257
Alexandre Lision67817192013-07-18 12:04:30 -0400258 Log.i(TAG, "PjSIPStack started");
259 managerImpl = SFLPhoneservice.instance();
260
261 /* set static AppPath before calling manager.init */
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400262// managerImpl.setPath(getApplication().getFilesDir().getAbsolutePath());
alision43a9b362013-05-01 16:30:15 -0400263
alision3ea8f3c2013-07-16 17:35:35 -0400264 callManagerJNI = new CallManager();
alision43a9b362013-05-01 16:30:15 -0400265 callManagerCallBack = new CallManagerCallBack(this);
266 SFLPhoneservice.setCallbackObject(callManagerCallBack);
267
alision3ea8f3c2013-07-16 17:35:35 -0400268 configurationManagerJNI = new ConfigurationManager();
alision43a9b362013-05-01 16:30:15 -0400269 configurationManagerCallback = new ConfigurationManagerCallback(this);
270 SFLPhoneservice.setConfigurationCallbackObject(configurationManagerCallback);
Alexandre Lision67817192013-07-18 12:04:30 -0400271 managerImpl.init("");
Adrien Béraud9360f242013-09-19 11:07:42 +1000272
Alexandre Lision67817192013-07-18 12:04:30 -0400273 Log.i(TAG, "->startPjSipStack");
alision43a9b362013-05-01 16:30:15 -0400274 }
275
Adrien Béraud9360f242013-09-19 11:07:42 +1000276 public HashMap<String, SipCall> getCurrent_calls() {
alision2cb99562013-05-30 17:02:20 -0400277 return current_calls;
278 }
279
alision43a9b362013-05-01 16:30:15 -0400280 // Enforce same thread contract to ensure we do not call from somewhere else
281 public class SameThreadException extends Exception {
282 private static final long serialVersionUID = -905639124232613768L;
283
284 public SameThreadException() {
285 super("Should be launched from a single worker thread");
286 }
287 }
288
289 public abstract static class SipRunnable implements Runnable {
290 protected abstract void doRun() throws SameThreadException, RemoteException;
291
Adrien Béraud9360f242013-09-19 11:07:42 +1000292 @Override
alision43a9b362013-05-01 16:30:15 -0400293 public void run() {
294 try {
295 doRun();
296 } catch (SameThreadException e) {
297 Log.e(TAG, "Not done from same thread");
298 } catch (RemoteException e) {
299 Log.e(TAG, e.toString());
300 }
301 }
302 }
303
304 public abstract static class SipRunnableWithReturn implements Runnable {
305 Object obj = null;
306 boolean done = false;
307
308 protected abstract Object doRun() throws SameThreadException;
309
310 public Object getVal() {
311 return obj;
312 }
313
314 public boolean isDone() {
315 return done;
316 }
317
Adrien Béraud9360f242013-09-19 11:07:42 +1000318 @Override
alision43a9b362013-05-01 16:30:15 -0400319 public void run() {
320 try {
321 obj = doRun();
322 done = true;
323 } catch (SameThreadException e) {
324 Log.e(TAG, "Not done from same thread");
325 }
326 }
327 }
328
329 class StartRunnable extends SipRunnable {
330 @Override
331 protected void doRun() throws SameThreadException {
332 startPjSipStack();
333 }
334 }
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400335
336 class FinalizeRunnable extends SipRunnable {
337 @Override
338 protected void doRun() throws SameThreadException {
339 stopDaemon();
340 }
341 }
alision43a9b362013-05-01 16:30:15 -0400342
alision43a9b362013-05-01 16:30:15 -0400343 /* ************************************
344 *
345 * Implement public interface for the service
346 *
Alexandre Lision67817192013-07-18 12:04:30 -0400347 * *********************************
348 */
349
Emeric Vigier6119d782012-09-21 18:04:14 -0400350 private final ISipService.Stub mBinder = new ISipService.Stub() {
351
352 @Override
alisionfde875f2013-05-28 17:01:54 -0400353 public void placeCall(final SipCall call) {
Emeric Vigier6119d782012-09-21 18:04:14 -0400354 getExecutor().execute(new SipRunnable() {
355 @Override
356 protected void doRun() throws SameThreadException {
357 Log.i(TAG, "SipService.placeCall() thread running...");
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400358 callManagerJNI.placeCall(call.getAccount().getAccountID(), call.getCallId(), call.getContact().getPhones().get(0).getNumber());
Adrien Béraud9360f242013-09-19 11:07:42 +1000359
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400360 HashMap<String, String> details = CallDetailsHandler.convertSwigToNative(callManagerJNI.getCallDetails(call.getCallId()));
Alexandre Lisionebeb3662013-09-17 16:20:54 -0400361 // watchout timestamp stored by sflphone is in seconds
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400362 call.setTimestamp_start(Long.parseLong(details.get(ServiceConstants.call.TIMESTAMP_START)));
alision2cb99562013-05-30 17:02:20 -0400363 getCurrent_calls().put(call.getCallId(), call);
Adrien Béraud9360f242013-09-19 11:07:42 +1000364
Emeric Vigier6119d782012-09-21 18:04:14 -0400365 }
366 });
367 }
368
369 @Override
370 public void refuse(final String callID) {
371 getExecutor().execute(new SipRunnable() {
372 @Override
373 protected void doRun() throws SameThreadException {
374 Log.i(TAG, "SipService.refuse() thread running...");
375 callManagerJNI.refuse(callID);
376 }
377 });
378 }
379
380 @Override
381 public void accept(final String callID) {
382 getExecutor().execute(new SipRunnable() {
383 @Override
384 protected void doRun() throws SameThreadException {
Tristan Matthews40cf25e2013-07-24 13:45:15 -0400385 Log.i(TAG, "SipService.accept() thread running...");
Emeric Vigier6119d782012-09-21 18:04:14 -0400386 callManagerJNI.accept(callID);
387 }
388 });
389 }
390
391 @Override
392 public void hangUp(final String callID) {
393 getExecutor().execute(new SipRunnable() {
394 @Override
395 protected void doRun() throws SameThreadException {
396 Log.i(TAG, "SipService.hangUp() thread running...");
397 callManagerJNI.hangUp(callID);
398 }
399 });
400 }
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400401
402 @Override
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400403 public void hold(final String callID) {
404 getExecutor().execute(new SipRunnable() {
405 @Override
406 protected void doRun() throws SameThreadException {
407 Log.i(TAG, "SipService.hold() thread running...");
408 callManagerJNI.hold(callID);
409 }
410 });
411 }
412
413 @Override
414 public void unhold(final String callID) {
415 getExecutor().execute(new SipRunnable() {
416 @Override
417 protected void doRun() throws SameThreadException {
418 Log.i(TAG, "SipService.unhold() thread running...");
419 callManagerJNI.unhold(callID);
420 }
421 });
422 }
Adrien Béraud9360f242013-09-19 11:07:42 +1000423
Alexandre Lision6711ab22013-09-16 15:15:38 -0400424 @Override
425 public HashMap<String, String> getCallDetails(String callID) throws RemoteException {
426 class CallDetails extends SipRunnableWithReturn {
427 private String id;
428
429 CallDetails(String callID) {
430 id = callID;
431 }
432
433 @Override
434 protected StringMap doRun() throws SameThreadException {
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400435 Log.i(TAG, "SipService.getCallDetails() thread running...");
Alexandre Lision6711ab22013-09-16 15:15:38 -0400436 return callManagerJNI.getCallDetails(id);
437 }
438 }
439
440 CallDetails runInstance = new CallDetails(callID);
441 getExecutor().execute(runInstance);
442
443 while (!runInstance.isDone()) {
444 }
445 StringMap swigmap = (StringMap) runInstance.getVal();
446
447 HashMap<String, String> nativemap = CallDetailsHandler.convertSwigToNative(swigmap);
448
449 return nativemap;
Adrien Béraud9360f242013-09-19 11:07:42 +1000450
Alexandre Lision6711ab22013-09-16 15:15:38 -0400451 }
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400452
453 @Override
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400454 public void setAudioPlugin(final String audioPlugin) {
455 getExecutor().execute(new SipRunnable() {
alision371b77e2013-04-23 14:51:26 -0400456 @Override
457 protected void doRun() throws SameThreadException {
458 Log.i(TAG, "SipService.setAudioPlugin() thread running...");
459 configurationManagerJNI.setAudioPlugin(audioPlugin);
460 }
Alexandre Savard31d27c62012-10-04 16:05:08 -0400461 });
462 }
463
464 @Override
465 public String getCurrentAudioOutputPlugin() {
466 class CurrentAudioPlugin extends SipRunnableWithReturn {
467 @Override
468 protected String doRun() throws SameThreadException {
469 Log.i(TAG, "SipService.getCurrentAudioOutputPlugin() thread running...");
470 return configurationManagerJNI.getCurrentAudioOutputPlugin();
471 }
alision371b77e2013-04-23 14:51:26 -0400472 }
473 ;
Alexandre Savard31d27c62012-10-04 16:05:08 -0400474
475 CurrentAudioPlugin runInstance = new CurrentAudioPlugin();
476 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400477 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400478 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400479 }
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400480 return (String) runInstance.getVal();
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400481 }
Alexandre Savard713a34d2012-09-26 15:50:41 -0400482
483 @Override
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400484 public ArrayList<String> getAccountList() {
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400485 class AccountList extends SipRunnableWithReturn {
486 @Override
487 protected StringVect doRun() throws SameThreadException {
488 Log.i(TAG, "SipService.getAccountList() thread running...");
489 return configurationManagerJNI.getAccountList();
490 }
alision371b77e2013-04-23 14:51:26 -0400491 }
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400492 AccountList runInstance = new AccountList();
Alexandre Lisioncdec5952013-07-17 14:18:22 -0400493 Log.i(TAG, "SipService.getAccountList() thread running...");
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400494 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400495 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400496 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400497 }
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400498 StringVect swigvect = (StringVect) runInstance.getVal();
499
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400500 ArrayList<String> nativelist = new ArrayList<String>();
Alexandre Savard52a72522012-09-27 16:40:13 -0400501
alision371b77e2013-04-23 14:51:26 -0400502 for (int i = 0; i < swigvect.size(); i++)
503 nativelist.add(swigvect.get(i));
Alexandre Savard52a72522012-09-27 16:40:13 -0400504
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400505 return nativelist;
alision371b77e2013-04-23 14:51:26 -0400506 }
Alexandre Lision4b4233a2013-10-16 17:24:17 -0400507
Alexandre Lision4cf78702013-10-16 13:43:23 -0400508 @Override
Alexandre Lision4b4233a2013-10-16 17:24:17 -0400509 public void setAccountOrder(final String order) {
Alexandre Lision4cf78702013-10-16 13:43:23 -0400510 getExecutor().execute(new SipRunnable() {
511 @Override
512 protected void doRun() throws SameThreadException {
513 Log.i(TAG, "SipService.setAccountsOrder() thread running...");
514 configurationManagerJNI.setAccountsOrder(order);
515 }
516 });
517 }
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400518
519 @Override
alision371b77e2013-04-23 14:51:26 -0400520 public HashMap<String, String> getAccountDetails(final String accountID) {
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400521 class AccountDetails extends SipRunnableWithReturn {
522 private String id;
alision371b77e2013-04-23 14:51:26 -0400523
524 AccountDetails(String accountId) {
525 id = accountId;
526 }
527
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400528 @Override
529 protected StringMap doRun() throws SameThreadException {
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400530 Log.i(TAG, "SipService.getAccountDetails() thread running...");
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400531 return configurationManagerJNI.getAccountDetails(id);
532 }
alision371b77e2013-04-23 14:51:26 -0400533 }
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400534
535 AccountDetails runInstance = new AccountDetails(accountID);
536 getExecutor().execute(runInstance);
alisionfde875f2013-05-28 17:01:54 -0400537
alision371b77e2013-04-23 14:51:26 -0400538 while (!runInstance.isDone()) {
539 }
540 StringMap swigmap = (StringMap) runInstance.getVal();
Alexandre Savard713a34d2012-09-26 15:50:41 -0400541
Alexandre Savard3bbb4792012-10-05 11:30:01 -0400542 HashMap<String, String> nativemap = AccountDetailsHandler.convertSwigToNative(swigmap);
Alexandre Savard713a34d2012-09-26 15:50:41 -0400543
544 return nativemap;
545 }
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400546
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400547 @SuppressWarnings("unchecked")
548 // Hashmap runtime cast
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400549 @Override
alisioncc7bb422013-06-06 15:31:39 -0400550 public void setAccountDetails(final String accountId, final Map map) {
alision371b77e2013-04-23 14:51:26 -0400551 HashMap<String, String> nativemap = (HashMap<String, String>) map;
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400552
Alexandre Savard3bbb4792012-10-05 11:30:01 -0400553 final StringMap swigmap = AccountDetailsHandler.convertFromNativeToSwig(nativemap);
Alexandre Savard718d49f2012-10-02 15:17:13 -0400554
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400555 getExecutor().execute(new SipRunnable() {
556 @Override
557 protected void doRun() throws SameThreadException {
alisioncc7bb422013-06-06 15:31:39 -0400558
559 configurationManagerJNI.setCredentials(accountId, extractCredentials(map));
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400560 configurationManagerJNI.setAccountDetails(accountId, swigmap);
alisioncc7bb422013-06-06 15:31:39 -0400561
Alexandre Lisionafd40e42013-10-15 13:48:37 -0400562 // convertSwigToNative(configurationManagerJNI.getCredentials(accountId));
alisioncc7bb422013-06-06 15:31:39 -0400563 Log.i(TAG, "SipService.setAccountDetails() thread running...");
564 }
565
566 private VectMap extractCredentials(Map map) {
567 VectMap swigmap = new VectMap();
568 StringMap entry = new StringMap();
alision5cfc35d2013-07-11 15:11:39 -0400569 entry.set(AccountDetailBasic.CONFIG_ACCOUNT_USERNAME, (String) map.get(AccountDetailBasic.CONFIG_ACCOUNT_USERNAME));
570 if ((String) map.get(AccountDetailBasic.CONFIG_ACCOUNT_REALM) != null)
571 entry.set(AccountDetailBasic.CONFIG_ACCOUNT_REALM, (String) map.get(AccountDetailBasic.CONFIG_ACCOUNT_REALM));
alisioncc7bb422013-06-06 15:31:39 -0400572 else
alision5cfc35d2013-07-11 15:11:39 -0400573 entry.set(AccountDetailBasic.CONFIG_ACCOUNT_REALM, "*");
574 entry.set(AccountDetailBasic.CONFIG_ACCOUNT_PASSWORD, (String) map.get(AccountDetailBasic.CONFIG_ACCOUNT_PASSWORD));
alisioncc7bb422013-06-06 15:31:39 -0400575 swigmap.add(entry);
576 return swigmap;
577
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400578 }
579 });
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400580 }
581
Alexandre Lisionafd40e42013-10-15 13:48:37 -0400582 // public ArrayList<HashMap<String, String>> convertSwigToNative(VectMap swigmap) {
583 //
584 // ArrayList<HashMap<String, String>> nativemap = new ArrayList<HashMap<String, String>>();
585 // Log.i(TAG, "swigmap size " + swigmap.size());
586 // for (int i = 0; i < swigmap.size(); ++i) {
587 // Log.i(TAG, "Entry " + i);
588 // StringMap tmp = swigmap.get(i);
589 // Log.i(TAG, tmp.get(AccountDetailBasic.CONFIG_ACCOUNT_USERNAME));
590 // // Log.i(TAG, tmp.get(ServiceConstants.CONFIG_ACCOUNT_REALM));
591 // Log.i(TAG, tmp.get(AccountDetailBasic.CONFIG_ACCOUNT_PASSWORD));
592 // }
593 //
594 // return nativemap;
595 // }
alisioncc7bb422013-06-06 15:31:39 -0400596
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400597 @SuppressWarnings("unchecked")
598 // Hashmap runtime cast
Alexandre Savard46036572012-10-05 13:56:49 -0400599 @Override
600 public String addAccount(Map map) {
601 class AddAccount extends SipRunnableWithReturn {
602 StringMap map;
alision371b77e2013-04-23 14:51:26 -0400603
604 AddAccount(StringMap m) {
605 map = m;
606 }
607
Alexandre Savard46036572012-10-05 13:56:49 -0400608 @Override
609 protected String doRun() throws SameThreadException {
610 Log.i(TAG, "SipService.getAccountDetails() thread running...");
611 return configurationManagerJNI.addAccount(map);
612 }
alision371b77e2013-04-23 14:51:26 -0400613 }
Alexandre Savard46036572012-10-05 13:56:49 -0400614
alision371b77e2013-04-23 14:51:26 -0400615 final StringMap swigmap = AccountDetailsHandler.convertFromNativeToSwig((HashMap<String, String>) map);
Alexandre Savard46036572012-10-05 13:56:49 -0400616
617 AddAccount runInstance = new AddAccount(swigmap);
618 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400619 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400620 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400621 }
Alexandre Savard46036572012-10-05 13:56:49 -0400622 String accountId = (String) runInstance.getVal();
623
624 return accountId;
625 }
626
627 @Override
628 public void removeAccount(final String accountId) {
629 getExecutor().execute(new SipRunnable() {
630 @Override
631 protected void doRun() throws SameThreadException {
632 Log.i(TAG, "SipService.setAccountDetails() thread running...");
633 configurationManagerJNI.removeAccount(accountId);
634 }
635 });
636 }
alision5f899632013-04-22 17:26:56 -0400637
alisione2a38e12013-04-25 14:20:20 -0400638 @Override
639 public ArrayList<HashMap<String, String>> getHistory() throws RemoteException {
640 class History extends SipRunnableWithReturn {
641
642 @Override
643 protected VectMap doRun() throws SameThreadException {
644 Log.i(TAG, "SipService.getHistory() thread running...");
alision7f18fc82013-05-01 09:37:33 -0400645
alisione2a38e12013-04-25 14:20:20 -0400646 return configurationManagerJNI.getHistory();
647 }
648 }
649
650 History runInstance = new History();
651 getExecutor().execute(runInstance);
652 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400653 // Log.w(TAG, "Waiting for getHistory");
alisione2a38e12013-04-25 14:20:20 -0400654 }
alision1005ba12013-06-19 13:52:44 -0400655 Log.i(TAG, "SipService.getHistory() DONE");
alisione2a38e12013-04-25 14:20:20 -0400656 VectMap swigmap = (VectMap) runInstance.getVal();
657
658 ArrayList<HashMap<String, String>> nativemap = HistoryHandler.convertSwigToNative(swigmap);
659
660 return nativemap;
661 }
alision7f18fc82013-05-01 09:37:33 -0400662
alision43a9b362013-05-01 16:30:15 -0400663 /*************************
664 * Transfer related API
665 *************************/
666
alision7f18fc82013-05-01 09:37:33 -0400667 @Override
668 public void transfer(final String callID, final String to) throws RemoteException {
669 getExecutor().execute(new SipRunnable() {
670 @Override
671 protected void doRun() throws SameThreadException, RemoteException {
672 Log.i(TAG, "SipService.transfer() thread running...");
673 if (callManagerJNI.transfer(callID, to)) {
674 Bundle bundle = new Bundle();
675 bundle.putString("CallID", callID);
676 bundle.putString("State", "HUNGUP");
677 Intent intent = new Intent(CallManagerCallBack.CALL_STATE_CHANGED);
alision7f18fc82013-05-01 09:37:33 -0400678 intent.putExtra("com.savoirfairelinux.sflphone.service.newstate", bundle);
alision84813a12013-05-27 17:40:39 -0400679 sendBroadcast(intent);
alision7f18fc82013-05-01 09:37:33 -0400680 } else
681 Log.i(TAG, "NOT OK");
682 }
683 });
684
685 }
alision43a9b362013-05-01 16:30:15 -0400686
alision7f18fc82013-05-01 09:37:33 -0400687 @Override
688 public void attendedTransfer(final String transferID, final String targetID) throws RemoteException {
689 getExecutor().execute(new SipRunnable() {
690 @Override
691 protected void doRun() throws SameThreadException, RemoteException {
alision43a9b362013-05-01 16:30:15 -0400692 Log.i(TAG, "SipService.attendedTransfer() thread running...");
alision7f18fc82013-05-01 09:37:33 -0400693 if (callManagerJNI.attendedTransfer(transferID, targetID)) {
694 Log.i(TAG, "OK");
alision7f18fc82013-05-01 09:37:33 -0400695 } else
696 Log.i(TAG, "NOT OK");
697 }
698 });
alision43a9b362013-05-01 16:30:15 -0400699
700 }
701
702 /*************************
703 * Conference related API
704 *************************/
705
706 @Override
707 public void removeConference(final String confID) throws RemoteException {
708 getExecutor().execute(new SipRunnable() {
709 @Override
710 protected void doRun() throws SameThreadException, RemoteException {
711 Log.i(TAG, "SipService.createConference() thread running...");
712 callManagerJNI.removeConference(confID);
713 }
714 });
715
alision7f18fc82013-05-01 09:37:33 -0400716 }
717
718 @Override
alision43a9b362013-05-01 16:30:15 -0400719 public void joinParticipant(final String sel_callID, final String drag_callID) throws RemoteException {
720 getExecutor().execute(new SipRunnable() {
721 @Override
722 protected void doRun() throws SameThreadException, RemoteException {
723 Log.i(TAG, "SipService.joinParticipant() thread running...");
724 callManagerJNI.joinParticipant(sel_callID, drag_callID);
alision806e18e2013-06-21 15:30:17 -0400725 // Generate a CONF_CREATED callback
alision43a9b362013-05-01 16:30:15 -0400726 }
727 });
728
alision7f18fc82013-05-01 09:37:33 -0400729 }
730
alision7f18fc82013-05-01 09:37:33 -0400731 @Override
alision806e18e2013-06-21 15:30:17 -0400732 public void addParticipant(final SipCall call, final String confID) throws RemoteException {
alision43a9b362013-05-01 16:30:15 -0400733 getExecutor().execute(new SipRunnable() {
734 @Override
735 protected void doRun() throws SameThreadException, RemoteException {
736 Log.i(TAG, "SipService.addParticipant() thread running...");
alision806e18e2013-06-21 15:30:17 -0400737 callManagerJNI.addParticipant(call.getCallId(), confID);
738 current_confs.get(confID).getParticipants().add(call);
alision43a9b362013-05-01 16:30:15 -0400739 }
740 });
741
alision7f18fc82013-05-01 09:37:33 -0400742 }
743
744 @Override
alision43a9b362013-05-01 16:30:15 -0400745 public void addMainParticipant(final String confID) throws RemoteException {
746 getExecutor().execute(new SipRunnable() {
747 @Override
748 protected void doRun() throws SameThreadException, RemoteException {
749 Log.i(TAG, "SipService.addMainParticipant() thread running...");
750 callManagerJNI.addMainParticipant(confID);
751 }
752 });
753
alision7f18fc82013-05-01 09:37:33 -0400754 }
755
756 @Override
alision43a9b362013-05-01 16:30:15 -0400757 public void detachParticipant(final String callID) throws RemoteException {
758 getExecutor().execute(new SipRunnable() {
759 @Override
760 protected void doRun() throws SameThreadException, RemoteException {
761 Log.i(TAG, "SipService.detachParticipant() thread running...");
alision806e18e2013-06-21 15:30:17 -0400762 Log.i(TAG, "Detaching " + callID);
763 Iterator<Entry<String, Conference>> it = current_confs.entrySet().iterator();
764 Log.i(TAG, "current_confs size " + current_confs.size());
765 while (it.hasNext()) {
766 Conference tmp = it.next().getValue();
767 Log.i(TAG, "conf has " + tmp.getParticipants().size() + " participants");
768 if (tmp.contains(callID)) {
769 current_calls.put(callID, tmp.getCall(callID));
770 Log.i(TAG, "Call found and put in current_calls");
771 }
772 }
alision43a9b362013-05-01 16:30:15 -0400773 callManagerJNI.detachParticipant(callID);
774 }
775 });
776
alision7f18fc82013-05-01 09:37:33 -0400777 }
778
779 @Override
alision43a9b362013-05-01 16:30:15 -0400780 public void joinConference(final String sel_confID, final String drag_confID) throws RemoteException {
781 getExecutor().execute(new SipRunnable() {
782 @Override
783 protected void doRun() throws SameThreadException, RemoteException {
784 Log.i(TAG, "SipService.joinConference() thread running...");
785 callManagerJNI.joinConference(sel_confID, drag_confID);
786 }
787 });
788
alision7f18fc82013-05-01 09:37:33 -0400789 }
790
791 @Override
alision43a9b362013-05-01 16:30:15 -0400792 public void hangUpConference(final String confID) throws RemoteException {
793 getExecutor().execute(new SipRunnable() {
794 @Override
795 protected void doRun() throws SameThreadException, RemoteException {
796 Log.i(TAG, "SipService.joinConference() thread running...");
797 callManagerJNI.hangUpConference(confID);
798 }
799 });
800
alision7f18fc82013-05-01 09:37:33 -0400801 }
802
803 @Override
alision43a9b362013-05-01 16:30:15 -0400804 public void holdConference(final String confID) throws RemoteException {
805 getExecutor().execute(new SipRunnable() {
806 @Override
807 protected void doRun() throws SameThreadException, RemoteException {
808 Log.i(TAG, "SipService.holdConference() thread running...");
809 callManagerJNI.holdConference(confID);
810 }
811 });
812
alision7f18fc82013-05-01 09:37:33 -0400813 }
814
815 @Override
alision43a9b362013-05-01 16:30:15 -0400816 public void unholdConference(final String confID) throws RemoteException {
817 getExecutor().execute(new SipRunnable() {
818 @Override
819 protected void doRun() throws SameThreadException, RemoteException {
820 Log.i(TAG, "SipService.unholdConference() thread running...");
821 callManagerJNI.unholdConference(confID);
822 }
823 });
824
alision7f18fc82013-05-01 09:37:33 -0400825 }
Alexandre Lision67817192013-07-18 12:04:30 -0400826
alisioncd8fb912013-06-28 14:43:51 -0400827 @Override
828 public boolean isConferenceParticipant(final String callID) throws RemoteException {
829 class IsParticipant extends SipRunnableWithReturn {
830
831 @Override
832 protected Boolean doRun() throws SameThreadException {
833 Log.i(TAG, "SipService.isRecording() thread running...");
834 return callManagerJNI.isConferenceParticipant(callID);
835 }
836 }
837
838 IsParticipant runInstance = new IsParticipant();
839 getExecutor().execute(runInstance);
840 while (!runInstance.isDone()) {
841 }
842
843 return (Boolean) runInstance.getVal();
844 }
alision7f18fc82013-05-01 09:37:33 -0400845
846 @Override
alisiondf1dac92013-06-27 17:35:53 -0400847 public HashMap<String, Conference> getConferenceList() throws RemoteException {
Alexandre Lision67817192013-07-18 12:04:30 -0400848 // class ConfList extends SipRunnableWithReturn {
849 // @Override
850 // protected StringVect doRun() throws SameThreadException {
851 // Log.i(TAG, "SipService.getConferenceList() thread running...");
852 // return callManagerJNI.getConferenceList();
853 // }
854 // }
855 // ;
856 // ConfList runInstance = new ConfList();
857 // getExecutor().execute(runInstance);
858 // while (!runInstance.isDone()) {
859 // // Log.w(TAG, "Waiting for getConferenceList");
860 // }
861 // StringVect swigvect = (StringVect) runInstance.getVal();
862 //
863 // ArrayList<String> nativelist = new ArrayList<String>();
864 //
865 // for (int i = 0; i < swigvect.size(); i++)
866 // nativelist.add(swigvect.get(i));
867 //
868 // return nativelist;
alisiondf1dac92013-06-27 17:35:53 -0400869 return current_confs;
alision7f18fc82013-05-01 09:37:33 -0400870 }
871
872 @Override
alision907bde72013-06-20 14:40:37 -0400873 public List getParticipantList(final String confID) throws RemoteException {
874 class PartList extends SipRunnableWithReturn {
875 @Override
876 protected StringVect doRun() throws SameThreadException {
877 Log.i(TAG, "SipService.getAccountList() thread running...");
878 return callManagerJNI.getParticipantList(confID);
879 }
880 }
881 ;
882 PartList runInstance = new PartList();
883 getExecutor().execute(runInstance);
884 while (!runInstance.isDone()) {
885 // Log.w(TAG, "Waiting for getConferenceList");
886 }
887 StringVect swigvect = (StringVect) runInstance.getVal();
888
889 ArrayList<String> nativelist = new ArrayList<String>();
890
891 for (int i = 0; i < swigvect.size(); i++)
892 nativelist.add(swigvect.get(i));
893
894 return nativelist;
alision7f18fc82013-05-01 09:37:33 -0400895 }
alision806e18e2013-06-21 15:30:17 -0400896
alision1005ba12013-06-19 13:52:44 -0400897 @Override
alision7f18fc82013-05-01 09:37:33 -0400898 public String getConferenceId(String callID) throws RemoteException {
alision43a9b362013-05-01 16:30:15 -0400899 Log.e(TAG, "getConferenceList not implemented");
alision7f18fc82013-05-01 09:37:33 -0400900 return null;
901 }
902
903 @Override
alision806e18e2013-06-21 15:30:17 -0400904 public String getConferenceDetails(final String callID) throws RemoteException {
905 class ConfDetails extends SipRunnableWithReturn {
906 @Override
907 protected StringMap doRun() throws SameThreadException {
908 Log.i(TAG, "SipService.getAccountList() thread running...");
909 return callManagerJNI.getConferenceDetails(callID);
910 }
911 }
912 ;
913 ConfDetails runInstance = new ConfDetails();
914 getExecutor().execute(runInstance);
915 while (!runInstance.isDone()) {
916 // Log.w(TAG, "Waiting for getConferenceList");
917 }
918 StringMap swigvect = (StringMap) runInstance.getVal();
919
920 return swigvect.get("CONF_STATE");
alision7f18fc82013-05-01 09:37:33 -0400921 }
922
alision04a00182013-05-10 17:05:29 -0400923 @Override
924 public String getRecordPath() throws RemoteException {
925 class RecordPath extends SipRunnableWithReturn {
926
927 @Override
928 protected String doRun() throws SameThreadException {
929 Log.i(TAG, "SipService.getRecordPath() thread running...");
Adrien Béraud9360f242013-09-19 11:07:42 +1000930 return configurationManagerJNI.getRecordPath();
alision04a00182013-05-10 17:05:29 -0400931 }
932 }
933
934 RecordPath runInstance = new RecordPath();
935 getExecutor().execute(runInstance);
936 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400937 // Log.w(TAG, "Waiting for getRecordPath");
alision04a00182013-05-10 17:05:29 -0400938 }
939 String path = (String) runInstance.getVal();
940
941 return path;
942 }
943
944 @Override
Alexandre Lisiona764c682013-09-09 10:02:07 -0400945 public boolean toggleRecordingCall(final String id) throws RemoteException {
Adrien Béraud9360f242013-09-19 11:07:42 +1000946
Alexandre Lisiona764c682013-09-09 10:02:07 -0400947 class ToggleRecording extends SipRunnableWithReturn {
948
alision04a00182013-05-10 17:05:29 -0400949 @Override
Alexandre Lisiona764c682013-09-09 10:02:07 -0400950 protected Boolean doRun() throws SameThreadException {
951 Log.i(TAG, "SipService.toggleRecordingCall() thread running...");
952 return callManagerJNI.toggleRecording(id);
alision04a00182013-05-10 17:05:29 -0400953 }
Alexandre Lisiona764c682013-09-09 10:02:07 -0400954 }
955
956 ToggleRecording runInstance = new ToggleRecording();
957 getExecutor().execute(runInstance);
958 while (!runInstance.isDone()) {
959 }
960
961 return (Boolean) runInstance.getVal();
alision04a00182013-05-10 17:05:29 -0400962
963 }
Alexandre Lision67817192013-07-18 12:04:30 -0400964
alision50fa0722013-06-25 17:29:44 -0400965 @Override
alisiondf1dac92013-06-27 17:35:53 -0400966 public boolean isRecording(final String id) throws RemoteException {
967 class IsRecording extends SipRunnableWithReturn {
968
969 @Override
970 protected Boolean doRun() throws SameThreadException {
971 Log.i(TAG, "SipService.isRecording() thread running...");
972 return callManagerJNI.getIsRecording(id);
973 }
974 }
975
976 IsRecording runInstance = new IsRecording();
977 getExecutor().execute(runInstance);
978 while (!runInstance.isDone()) {
979 }
980
981 return (Boolean) runInstance.getVal();
Alexandre Lision67817192013-07-18 12:04:30 -0400982
alisiondf1dac92013-06-27 17:35:53 -0400983 }
Alexandre Lision67817192013-07-18 12:04:30 -0400984
alisiondf1dac92013-06-27 17:35:53 -0400985 @Override
alision50fa0722013-06-25 17:29:44 -0400986 public boolean startRecordedFilePlayback(final String filepath) throws RemoteException {
987 getExecutor().execute(new SipRunnable() {
988 @Override
989 protected void doRun() throws SameThreadException, RemoteException {
990 Log.i(TAG, "SipService.setRecordingCall() thread running...");
991 callManagerJNI.startRecordedFilePlayback(filepath);
992 }
993 });
994 return false;
995 }
996
997 @Override
998 public void stopRecordedFilePlayback(final String filepath) throws RemoteException {
999 getExecutor().execute(new SipRunnable() {
1000 @Override
1001 protected void doRun() throws SameThreadException, RemoteException {
1002 Log.i(TAG, "SipService.stopRecordedFilePlayback() thread running...");
1003 callManagerJNI.stopRecordedFilePlayback(filepath);
1004 }
1005 });
1006 }
alision04a00182013-05-10 17:05:29 -04001007
1008 @Override
1009 public void setRecordPath(final String path) throws RemoteException {
1010 getExecutor().execute(new SipRunnable() {
1011 @Override
1012 protected void doRun() throws SameThreadException, RemoteException {
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001013 Log.i(TAG, "SipService.setRecordPath() " + path + " thread running...");
Adrien Béraud9360f242013-09-19 11:07:42 +10001014 configurationManagerJNI.setRecordPath(path);
alision04a00182013-05-10 17:05:29 -04001015 }
1016 });
1017 }
1018
1019 @Override
1020 public void sendTextMessage(final String callID, final String message, final String from) throws RemoteException {
1021 getExecutor().execute(new SipRunnable() {
1022 @Override
1023 protected void doRun() throws SameThreadException, RemoteException {
1024 Log.i(TAG, "SipService.sendTextMessage() thread running...");
Alexandre Lision10314352013-07-17 15:06:56 -04001025 callManagerJNI.sendTextMessage(callID, message);
alision04a00182013-05-10 17:05:29 -04001026 }
1027 });
1028
1029 }
1030
alisiond295ec22013-05-17 10:12:13 -04001031 @Override
Alexandre Lision4cf78702013-10-16 13:43:23 -04001032 public List getAudioCodecList(final String accountID) throws RemoteException {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001033 class AudioCodecList extends SipRunnableWithReturn {
1034
1035 @Override
Alexandre Lision933ef0a2013-10-15 17:28:40 -04001036 protected ArrayList<Codec> doRun() throws SameThreadException {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001037 Log.i(TAG, "SipService.getAudioCodecList() thread running...");
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001038 ArrayList<Codec> results = new ArrayList<Codec>();
Alexandre Lision4cf78702013-10-16 13:43:23 -04001039
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001040 IntVect active_payloads = configurationManagerJNI.getActiveAudioCodecList(accountID);
1041 for (int i = 0; i < active_payloads.size(); ++i) {
1042
Alexandre Lision039a3cf2013-10-16 17:44:57 -04001043 results.add(new Codec(active_payloads.get(i), configurationManagerJNI.getAudioCodecDetails(active_payloads.get(i)), true));
Alexandre Lisione0045442013-10-25 09:16:19 -04001044
Alexandre Lision4cf78702013-10-16 13:43:23 -04001045 }
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001046
Alexandre Lision039a3cf2013-10-16 17:44:57 -04001047 // if (results.get(active_payloads.get(i)) != null) {
1048 // results.get(active_payloads.get(i)).setEnabled(true);
1049
1050 IntVect payloads = configurationManagerJNI.getAudioCodecList();
1051
1052 for (int i = 0; i < payloads.size(); ++i) {
1053 boolean isActive = false;
1054 for (Codec co : results) {
1055 if (co.getPayload().toString().contentEquals(String.valueOf(payloads.get(i))))
1056 isActive = true;
1057
1058 }
1059 if (isActive)
1060 continue;
1061 else
1062 results.add(new Codec(payloads.get(i), configurationManagerJNI.getAudioCodecDetails(payloads.get(i)), false));
1063
1064 }
1065
1066 // if (!results.containsKey(payloads.get(i))) {
1067 // results.put(payloads.get(i), new Codec(payloads.get(i), configurationManagerJNI.getAudioCodecDetails(payloads.get(i)), false));
1068 // Log.i(TAG, "Other, Adding:" + results.get((payloads.get(i))).getName());
1069 // }
1070
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001071 return results;
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001072 }
1073 }
1074
1075 AudioCodecList runInstance = new AudioCodecList();
1076 getExecutor().execute(runInstance);
1077 while (!runInstance.isDone()) {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001078 }
Alexandre Lision933ef0a2013-10-15 17:28:40 -04001079 ArrayList<Codec> codecs = (ArrayList<Codec>) runInstance.getVal();
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001080 return codecs;
alisiond295ec22013-05-17 10:12:13 -04001081 }
1082
alision9f7a6ec2013-05-24 16:26:26 -04001083 @Override
Alexandre Lision4cf78702013-10-16 13:43:23 -04001084 public Map getRingtoneList() throws RemoteException {
1085 class RingtoneList extends SipRunnableWithReturn {
1086
1087 @Override
1088 protected StringMap doRun() throws SameThreadException {
1089 Log.i(TAG, "SipService.getRingtoneList() thread running...");
1090 return configurationManagerJNI.getRingtoneList();
1091 }
1092 }
1093
1094 RingtoneList runInstance = new RingtoneList();
1095 getExecutor().execute(runInstance);
1096 while (!runInstance.isDone()) {
1097 }
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001098 StringMap ringtones = (StringMap) runInstance.getVal();
1099
1100 for (int i = 0; i < ringtones.size(); ++i) {
1101 // Log.i(TAG,"ringtones "+i+" "+ ringtones.);
1102 }
1103
Alexandre Lision4cf78702013-10-16 13:43:23 -04001104 return null;
1105 }
1106
1107 @Override
1108 public void setActiveCodecList(final List codecs, final String accountID) throws RemoteException {
1109 getExecutor().execute(new SipRunnable() {
1110 @Override
1111 protected void doRun() throws SameThreadException, RemoteException {
1112 Log.i(TAG, "SipService.setActiveAudioCodecList() thread running...");
1113 StringVect list = new StringVect();
1114 for (int i = 0; i < codecs.size(); ++i) {
1115 list.add((String) codecs.get(i));
1116 }
1117 configurationManagerJNI.setActiveAudioCodecList(list, accountID);
1118 }
1119 });
1120 }
1121
1122 @Override
alisionfde875f2013-05-28 17:01:54 -04001123 public HashMap<String, SipCall> getCallList() throws RemoteException {
alision85704182013-05-29 15:23:03 -04001124 // class CallList extends SipRunnableWithReturn {
1125 //
1126 // @Override
1127 // protected StringVect doRun() throws SameThreadException {
1128 // Log.i(TAG, "SipService.getCallList() thread running...");
1129 // return callManagerJNI.getCallList();
1130 // }
1131 // }
1132 //
1133 // CallList runInstance = new CallList();
1134 // getExecutor().execute(runInstance);
1135 // while (!runInstance.isDone()) {
1136 // Log.w(TAG, "Waiting for getAudioCodecList");
1137 // }
1138 // StringVect swigmap = (StringVect) runInstance.getVal();
1139 //
1140 // ArrayList<String> nativemap = new ArrayList<String>();
1141 // for (int i = 0; i < swigmap.size(); ++i) {
1142 //
1143 // String t = swigmap.get(i);
1144 // nativemap.add(t);
1145 // }
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001146 // if(callManagerJNI == null)
1147 // return new HashMap<String, SipCall>();
1148 //
1149 //
1150 // HashMap<String, SipCall> results = new HashMap<String, SipCall>();
1151 // StringVect calls = callManagerJNI.getCallList();
1152 // for(int i = 0 ; i < calls.size(); ++i){
1153 // results.put(calls.get(i), new SipCall(calls.get(i), callManagerJNI.getCallDetails(calls.get(i))));
1154 // }
alision9f7a6ec2013-05-24 16:26:26 -04001155
alision2cb99562013-05-30 17:02:20 -04001156 return getCurrent_calls();
alision9f7a6ec2013-05-24 16:26:26 -04001157 }
1158
alision85704182013-05-29 15:23:03 -04001159 @Override
1160 public SipCall getCall(String callID) throws RemoteException {
alision2cb99562013-05-30 17:02:20 -04001161 return getCurrent_calls().get(callID);
1162 }
1163
1164 /***********************
1165 * Notification API
1166 ***********************/
1167 @Override
1168 public void createNotification() throws RemoteException {
1169 makeNotification();
alisioncc7bb422013-06-06 15:31:39 -04001170
alision2cb99562013-05-30 17:02:20 -04001171 }
1172
1173 @Override
1174 public void destroyNotification() throws RemoteException {
1175 removeNotification();
alisioncc7bb422013-06-06 15:31:39 -04001176
alision2cb99562013-05-30 17:02:20 -04001177 }
alisioncc7bb422013-06-06 15:31:39 -04001178
Adrien Béraud9360f242013-09-19 11:07:42 +10001179 private final int NOTIFICATION_ID = new Random().nextInt(1000);
alisioncc7bb422013-06-06 15:31:39 -04001180
alision2cb99562013-05-30 17:02:20 -04001181 private void makeNotification() {
alisioncc7bb422013-06-06 15:31:39 -04001182 if (current_calls.size() == 0) {
alision2cb99562013-05-30 17:02:20 -04001183 return;
1184 }
1185 Intent notificationIntent = new Intent(getApplicationContext(), SFLPhoneHomeActivity.class);
alisioncc7bb422013-06-06 15:31:39 -04001186 PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 007, notificationIntent,
1187 PendingIntent.FLAG_UPDATE_CURRENT);
alision2cb99562013-05-30 17:02:20 -04001188
1189 NotificationManager nm = (NotificationManager) getBaseContext().getSystemService(Context.NOTIFICATION_SERVICE);
Adrien Béraud9360f242013-09-19 11:07:42 +10001190 nm.cancel(NOTIFICATION_ID); // clear previous notifications.
alision2cb99562013-05-30 17:02:20 -04001191
1192 NotificationCompat.Builder builder = new NotificationCompat.Builder(getBaseContext());
alisioncc7bb422013-06-06 15:31:39 -04001193 //
1194 // builder.setContent(view);
1195 builder.setContentIntent(contentIntent).setOngoing(true).setSmallIcon(R.drawable.ic_launcher)
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001196 .setContentTitle(getCurrent_calls().size() + " ongoing calls").setTicker("Pending calls").setWhen(System.currentTimeMillis())
1197 .setAutoCancel(false);
alision2cb99562013-05-30 17:02:20 -04001198 builder.setPriority(NotificationCompat.PRIORITY_MAX);
1199 Notification n = builder.build();
1200
1201 nm.notify(NOTIFICATION_ID, n);
alision2cb99562013-05-30 17:02:20 -04001202 }
1203
1204 public void removeNotification() {
1205 NotificationManager nm = (NotificationManager) getBaseContext().getSystemService(Context.NOTIFICATION_SERVICE);
1206 nm.cancel(NOTIFICATION_ID);
alision85704182013-05-29 15:23:03 -04001207 }
1208
alisiondf1dac92013-06-27 17:35:53 -04001209 @Override
1210 public Conference getCurrentCall() throws RemoteException {
Alexandre Lision67817192013-07-18 12:04:30 -04001211 for (SipCall i : current_calls.values()) {
Adrien Béraud9360f242013-09-19 11:07:42 +10001212
Alexandre Lisionc51ccb12013-09-11 16:00:30 -04001213 // Incoming >> Ongoing
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001214 if (i.isIncoming()) {
Alexandre Lisionc51ccb12013-09-11 16:00:30 -04001215 Conference tmp = new Conference("-1");
1216 tmp.getParticipants().add(i);
1217 return tmp;
1218 }
Adrien Béraud9360f242013-09-19 11:07:42 +10001219
Alexandre Lision67817192013-07-18 12:04:30 -04001220 if (i.isOngoing()) {
alisiondf1dac92013-06-27 17:35:53 -04001221 Conference tmp = new Conference("-1");
1222 tmp.getParticipants().add(i);
1223 return tmp;
1224 }
1225 }
Alexandre Lision67817192013-07-18 12:04:30 -04001226
1227 if (!current_confs.isEmpty()) {
alisiondf1dac92013-06-27 17:35:53 -04001228 return (Conference) current_confs.values().toArray()[0];
1229 }
1230 return null;
1231 }
1232
Alexandre Lision64dc8c02013-09-25 15:32:25 -04001233 @Override
1234 public void playDtmf(final String key) throws RemoteException {
1235 getExecutor().execute(new SipRunnable() {
1236 @Override
1237 protected void doRun() throws SameThreadException, RemoteException {
1238 Log.i(TAG, "SipService.playDtmf() thread running...");
1239 callManagerJNI.playDTMF(key);
1240 }
1241 });
1242 }
1243
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001244 @Override
1245 public List getConcurrentCalls() throws RemoteException {
1246 ArrayList<Conference> toReturn = new ArrayList<Conference>();
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001247
1248 for (SipCall sip : current_calls.values()) {
1249 if (!sip.isCurrent()) {
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001250 Conference tmp = new Conference("-1");
1251 tmp.getParticipants().add(sip);
1252 toReturn.add(tmp);
1253 }
1254 }
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001255
1256 Log.i(TAG, "toReturn SIZE " + toReturn.size());
1257
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001258 return toReturn;
1259 }
1260
Alexandre Lision4fb22622013-10-21 16:26:33 -04001261 @Override
1262 public String getCurrentAudioCodecName(String callID) throws RemoteException {
1263 return callManagerJNI.getCurrentAudioCodecName(callID);
1264 }
1265
Emeric Vigier6119d782012-09-21 18:04:14 -04001266 };
Alexandre Lision6d867b92013-10-25 15:36:28 -04001267
Alexandre Lision6d867b92013-10-25 15:36:28 -04001268 public void changeVolume(int currentVolume) {
Alexandre Lisiondd68f652013-10-28 11:00:12 -04001269 // StringVect resultsInput = configurationManagerJNI.getAudioInputDeviceList();
1270 // StringVect resultsOutput = configurationManagerJNI.getAudioOutputDeviceList();
1271 //
1272 // Log.i(TAG, "------------------> INPUT DEVICES");
1273 // for(int i = 0 ; i < resultsInput.size(); ++i){
1274 // Log.i(TAG, resultsInput.get(i));
1275 // }
1276 //
1277 // Log.i(TAG, "------------------> OUTPUT DEVICES");
1278 // for(int i = 0 ; i < resultsOutput.size(); ++i){
1279 // Log.i(TAG, resultsOutput.get(i));
1280 // }
1281
1282 // Log.i(TAG,"AudioManager ------------> "+configurationManagerJNI.getAudioManager());
1283
Alexandre Lision6d867b92013-10-25 15:36:28 -04001284 callManagerJNI.setVolume("speaker", currentVolume);
1285 }
Emeric Vigiereaf2c492012-09-19 14:38:20 -04001286}