blob: dfe9b3e90b4071384b80aa3baee582e8d9d83b42 [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
alision04a00182013-05-10 17:05:29 -040084
alision2cb99562013-05-30 17:02:20 -040085 private HashMap<String, SipCall> current_calls = new HashMap<String, SipCall>();
alision806e18e2013-06-21 15:30:17 -040086 private HashMap<String, Conference> current_confs = new HashMap<String, Conference>();
87 private IncomingReceiver receiver;
Alexandre Lision6d867b92013-10-25 15:36:28 -040088
Emeric Vigier6119d782012-09-21 18:04:14 -040089
alision806e18e2013-06-21 15:30:17 -040090 public HashMap<String, Conference> getCurrent_confs() {
91 return current_confs;
92 }
alision43a9b362013-05-01 16:30:15 -040093
94 @Override
95 public boolean onUnbind(Intent i) {
96 super.onUnbind(i);
97 Log.i(TAG, "onUnbind(intent)");
Alexandre Lision0f550ee2013-10-25 15:34:38 -040098 return true;
99 }
100
101 @Override
102 public void onRebind(Intent i){
103 super.onRebind(i);
alision43a9b362013-05-01 16:30:15 -0400104 }
105
106 /* called once by startService() */
107 @Override
108 public void onCreate() {
109 Log.i(TAG, "onCreated");
110 super.onCreate();
111
alision43a9b362013-05-01 16:30:15 -0400112
113 IntentFilter callFilter = new IntentFilter(CallManagerCallBack.CALL_STATE_CHANGED);
114 callFilter.addAction(CallManagerCallBack.INCOMING_CALL);
115 callFilter.addAction(CallManagerCallBack.NEW_CALL_CREATED);
alision4a0eb092013-05-07 13:52:03 -0400116 callFilter.addAction(ConfigurationManagerCallback.ACCOUNT_STATE_CHANGED);
117 callFilter.addAction(ConfigurationManagerCallback.ACCOUNTS_CHANGED);
alision04a00182013-05-10 17:05:29 -0400118 callFilter.addAction(CallManagerCallBack.INCOMING_TEXT);
alision806e18e2013-06-21 15:30:17 -0400119 callFilter.addAction(CallManagerCallBack.CONF_CREATED);
120 callFilter.addAction(CallManagerCallBack.CONF_REMOVED);
121 callFilter.addAction(CallManagerCallBack.CONF_CHANGED);
alisiondf1dac92013-06-27 17:35:53 -0400122 callFilter.addAction(CallManagerCallBack.RECORD_STATE_CHANGED);
alision806e18e2013-06-21 15:30:17 -0400123 receiver = new IncomingReceiver(this, mBinder);
alision2cb99562013-05-30 17:02:20 -0400124 LocalBroadcastManager.getInstance(this).registerReceiver(receiver, callFilter);
alision2cb99562013-05-30 17:02:20 -0400125
alisioncc7bb422013-06-06 15:31:39 -0400126 getExecutor().execute(new StartRunnable());
Alexandre Lisione0045442013-10-25 09:16:19 -0400127
128 notificationManager = new SipNotifications(this);
Alexandre Lision6d867b92013-10-25 15:36:28 -0400129 mediaManager = new MediaManager(this);
130
Alexandre Lisione0045442013-10-25 09:16:19 -0400131 notificationManager.onServiceCreate();
Alexandre Lision6d867b92013-10-25 15:36:28 -0400132 mediaManager.startService();
133
alisioncc7bb422013-06-06 15:31:39 -0400134 }
alision43a9b362013-05-01 16:30:15 -0400135
136 /* called for each startService() */
137 @Override
138 public int onStartCommand(Intent intent, int flags, int startId) {
139 Log.i(TAG, "onStarted");
140 super.onStartCommand(intent, flags, startId);
141
alision806e18e2013-06-21 15:30:17 -0400142 receiver = new IncomingReceiver(this, mBinder);
Alexandre Lisione0045442013-10-25 09:16:19 -0400143
alision43a9b362013-05-01 16:30:15 -0400144
Alexandre Lision0f550ee2013-10-25 15:34:38 -0400145 return START_STICKY; /* started and stopped explicitly */
alision43a9b362013-05-01 16:30:15 -0400146 }
147
148 @Override
149 public void onDestroy() {
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400150 Log.i(TAG, "onDestroyed");
alision43a9b362013-05-01 16:30:15 -0400151 /* called once by stopService() */
Alexandre Lisionafbe8f62013-10-25 15:52:44 -0400152
Alexandre Lision0a300ff2013-09-23 14:22:34 -0400153 LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
Alexandre Lisione0045442013-10-25 09:16:19 -0400154 notificationManager.onServiceDestroy();
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400155 // sflphoneApp.setServiceRunning(false);
Alexandre Lisionafbe8f62013-10-25 15:52:44 -0400156 Toast.makeText(this, "Sflphone Service stopped", Toast.LENGTH_SHORT).show();
157 managerImpl.finish();
158
alision43a9b362013-05-01 16:30:15 -0400159 super.onDestroy();
160
alision43a9b362013-05-01 16:30:15 -0400161 }
162
163 @Override
164 public IBinder onBind(Intent arg0) {
165 Log.i(TAG, "onBound");
166 return mBinder;
167 }
Alexandre Lisionafbe8f62013-10-25 15:52:44 -0400168
alision43a9b362013-05-01 16:30:15 -0400169 private static Looper createLooper() {
170 if (executorThread == null) {
171 Log.d(TAG, "Creating new handler thread");
172 // ADT gives a fake warning due to bad parse rule.
173 executorThread = new HandlerThread("SipService.Executor");
174 executorThread.start();
175 }
176 return executorThread.getLooper();
177 }
178
179 public SipServiceExecutor getExecutor() {
180 // create mExecutor lazily
181 if (mExecutor == null) {
182 mExecutor = new SipServiceExecutor(this);
183 }
184 return mExecutor;
185 }
186
187 // Executes immediate tasks in a single executorThread.
188 public static class SipServiceExecutor extends Handler {
189 WeakReference<SipService> handlerService;
190
191 SipServiceExecutor(SipService s) {
192 super(createLooper());
193 handlerService = new WeakReference<SipService>(s);
194 }
195
196 public void execute(Runnable task) {
197 // TODO: add wakelock
198 Message.obtain(this, 0/* don't care */, task).sendToTarget();
Alexandre Lisioncdec5952013-07-17 14:18:22 -0400199 Log.w(TAG, "SenT!");
alision43a9b362013-05-01 16:30:15 -0400200 }
201
202 @Override
203 public void handleMessage(Message msg) {
204 if (msg.obj instanceof Runnable) {
205 executeInternal((Runnable) msg.obj);
206 } else {
207 Log.w(TAG, "can't handle msg: " + msg);
208 }
209 }
210
211 private void executeInternal(Runnable task) {
212 try {
213 task.run();
214 } catch (Throwable t) {
215 Log.e(TAG, "run task: " + task, t);
216 }
217 }
218 }
219
220 private void startPjSipStack() throws SameThreadException {
221 if (isPjSipStackStarted)
222 return;
223
224 try {
225 System.loadLibrary("gnustl_shared");
226 System.loadLibrary("expat");
227 System.loadLibrary("yaml");
228 System.loadLibrary("ccgnu2");
229 System.loadLibrary("crypto");
230 System.loadLibrary("ssl");
Alexandre Lision7c6f4a62013-09-05 13:27:01 -0400231 System.loadLibrary("sndfile");
alision43a9b362013-05-01 16:30:15 -0400232 System.loadLibrary("ccrtp1");
alision43a9b362013-05-01 16:30:15 -0400233 System.loadLibrary("samplerate");
234 System.loadLibrary("codec_ulaw");
235 System.loadLibrary("codec_alaw");
Alexandre Lision0a300ff2013-09-23 14:22:34 -0400236 System.loadLibrary("codec_g722");
Alexandre Lision6deda412013-09-25 13:21:22 -0400237 System.loadLibrary("codec_opus");
Alexandre Lisiona1ad1c32013-10-15 16:35:20 -0400238 System.loadLibrary("codec_gsm");
Alexandre Lision62138172013-10-17 11:52:45 -0400239 System.loadLibrary("codec_speex_nb");
240 System.loadLibrary("codec_speex_ub");
241 System.loadLibrary("codec_speex_wb");
alision43a9b362013-05-01 16:30:15 -0400242 System.loadLibrary("speexresampler");
243 System.loadLibrary("sflphone");
244 isPjSipStackStarted = true;
Adrien Béraud9360f242013-09-19 11:07:42 +1000245
alision43a9b362013-05-01 16:30:15 -0400246 } catch (UnsatisfiedLinkError e) {
247 Log.e(TAG, "Problem with the current Pj stack...", e);
248 isPjSipStackStarted = false;
249 return;
250 } catch (Exception e) {
251 Log.e(TAG, "Problem with the current Pj stack...", e);
252 }
253
Alexandre Lision67817192013-07-18 12:04:30 -0400254 Log.i(TAG, "PjSIPStack started");
255 managerImpl = SFLPhoneservice.instance();
256
257 /* set static AppPath before calling manager.init */
258
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400259 // managerImpl.setPath(sflphoneApp.getAppPath());
alision43a9b362013-05-01 16:30:15 -0400260
alision3ea8f3c2013-07-16 17:35:35 -0400261 callManagerJNI = new CallManager();
alision43a9b362013-05-01 16:30:15 -0400262 callManagerCallBack = new CallManagerCallBack(this);
263 SFLPhoneservice.setCallbackObject(callManagerCallBack);
264
alision3ea8f3c2013-07-16 17:35:35 -0400265 configurationManagerJNI = new ConfigurationManager();
alision43a9b362013-05-01 16:30:15 -0400266 configurationManagerCallback = new ConfigurationManagerCallback(this);
267 SFLPhoneservice.setConfigurationCallbackObject(configurationManagerCallback);
Adrien Béraud9360f242013-09-19 11:07:42 +1000268
Alexandre Lision67817192013-07-18 12:04:30 -0400269 Log.i(TAG, "before init");
270 managerImpl.init("");
Adrien Béraud9360f242013-09-19 11:07:42 +1000271
Alexandre Lision67817192013-07-18 12:04:30 -0400272 Log.i(TAG, "->startPjSipStack");
alision43a9b362013-05-01 16:30:15 -0400273
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 }
335
alision43a9b362013-05-01 16:30:15 -0400336 /* ************************************
337 *
338 * Implement public interface for the service
339 *
Alexandre Lision67817192013-07-18 12:04:30 -0400340 * *********************************
341 */
342
Emeric Vigier6119d782012-09-21 18:04:14 -0400343 private final ISipService.Stub mBinder = new ISipService.Stub() {
344
345 @Override
alisionfde875f2013-05-28 17:01:54 -0400346 public void placeCall(final SipCall call) {
Emeric Vigier6119d782012-09-21 18:04:14 -0400347 getExecutor().execute(new SipRunnable() {
348 @Override
349 protected void doRun() throws SameThreadException {
350 Log.i(TAG, "SipService.placeCall() thread running...");
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400351 callManagerJNI.placeCall(call.getAccount().getAccountID(), call.getCallId(), call.getContact().getPhones().get(0).getNumber());
Adrien Béraud9360f242013-09-19 11:07:42 +1000352
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400353 HashMap<String, String> details = CallDetailsHandler.convertSwigToNative(callManagerJNI.getCallDetails(call.getCallId()));
Alexandre Lisionebeb3662013-09-17 16:20:54 -0400354 // watchout timestamp stored by sflphone is in seconds
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400355 call.setTimestamp_start(Long.parseLong(details.get(ServiceConstants.call.TIMESTAMP_START)));
alision2cb99562013-05-30 17:02:20 -0400356 getCurrent_calls().put(call.getCallId(), call);
Adrien Béraud9360f242013-09-19 11:07:42 +1000357
Emeric Vigier6119d782012-09-21 18:04:14 -0400358 }
359 });
360 }
361
362 @Override
363 public void refuse(final String callID) {
364 getExecutor().execute(new SipRunnable() {
365 @Override
366 protected void doRun() throws SameThreadException {
367 Log.i(TAG, "SipService.refuse() thread running...");
368 callManagerJNI.refuse(callID);
369 }
370 });
371 }
372
373 @Override
374 public void accept(final String callID) {
375 getExecutor().execute(new SipRunnable() {
376 @Override
377 protected void doRun() throws SameThreadException {
Tristan Matthews40cf25e2013-07-24 13:45:15 -0400378 Log.i(TAG, "SipService.accept() thread running...");
Emeric Vigier6119d782012-09-21 18:04:14 -0400379 callManagerJNI.accept(callID);
380 }
381 });
382 }
383
384 @Override
385 public void hangUp(final String callID) {
386 getExecutor().execute(new SipRunnable() {
387 @Override
388 protected void doRun() throws SameThreadException {
389 Log.i(TAG, "SipService.hangUp() thread running...");
390 callManagerJNI.hangUp(callID);
391 }
392 });
393 }
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400394
395 @Override
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400396 public void hold(final String callID) {
397 getExecutor().execute(new SipRunnable() {
398 @Override
399 protected void doRun() throws SameThreadException {
400 Log.i(TAG, "SipService.hold() thread running...");
401 callManagerJNI.hold(callID);
402 }
403 });
404 }
405
406 @Override
407 public void unhold(final String callID) {
408 getExecutor().execute(new SipRunnable() {
409 @Override
410 protected void doRun() throws SameThreadException {
411 Log.i(TAG, "SipService.unhold() thread running...");
412 callManagerJNI.unhold(callID);
413 }
414 });
415 }
Adrien Béraud9360f242013-09-19 11:07:42 +1000416
Alexandre Lision6711ab22013-09-16 15:15:38 -0400417 @Override
418 public HashMap<String, String> getCallDetails(String callID) throws RemoteException {
419 class CallDetails extends SipRunnableWithReturn {
420 private String id;
421
422 CallDetails(String callID) {
423 id = callID;
424 }
425
426 @Override
427 protected StringMap doRun() throws SameThreadException {
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400428 Log.i(TAG, "SipService.getCallDetails() thread running...");
Alexandre Lision6711ab22013-09-16 15:15:38 -0400429 return callManagerJNI.getCallDetails(id);
430 }
431 }
432
433 CallDetails runInstance = new CallDetails(callID);
434 getExecutor().execute(runInstance);
435
436 while (!runInstance.isDone()) {
437 }
438 StringMap swigmap = (StringMap) runInstance.getVal();
439
440 HashMap<String, String> nativemap = CallDetailsHandler.convertSwigToNative(swigmap);
441
442 return nativemap;
Adrien Béraud9360f242013-09-19 11:07:42 +1000443
Alexandre Lision6711ab22013-09-16 15:15:38 -0400444 }
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400445
446 @Override
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400447 public void setAudioPlugin(final String audioPlugin) {
448 getExecutor().execute(new SipRunnable() {
alision371b77e2013-04-23 14:51:26 -0400449 @Override
450 protected void doRun() throws SameThreadException {
451 Log.i(TAG, "SipService.setAudioPlugin() thread running...");
452 configurationManagerJNI.setAudioPlugin(audioPlugin);
453 }
Alexandre Savard31d27c62012-10-04 16:05:08 -0400454 });
455 }
456
457 @Override
458 public String getCurrentAudioOutputPlugin() {
459 class CurrentAudioPlugin extends SipRunnableWithReturn {
460 @Override
461 protected String doRun() throws SameThreadException {
462 Log.i(TAG, "SipService.getCurrentAudioOutputPlugin() thread running...");
463 return configurationManagerJNI.getCurrentAudioOutputPlugin();
464 }
alision371b77e2013-04-23 14:51:26 -0400465 }
466 ;
Alexandre Savard31d27c62012-10-04 16:05:08 -0400467
468 CurrentAudioPlugin runInstance = new CurrentAudioPlugin();
469 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400470 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400471 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400472 }
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400473 return (String) runInstance.getVal();
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400474 }
Alexandre Savard713a34d2012-09-26 15:50:41 -0400475
476 @Override
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400477 public ArrayList<String> getAccountList() {
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400478 class AccountList extends SipRunnableWithReturn {
479 @Override
480 protected StringVect doRun() throws SameThreadException {
481 Log.i(TAG, "SipService.getAccountList() thread running...");
482 return configurationManagerJNI.getAccountList();
483 }
alision371b77e2013-04-23 14:51:26 -0400484 }
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400485 AccountList runInstance = new AccountList();
Alexandre Lisioncdec5952013-07-17 14:18:22 -0400486 Log.i(TAG, "SipService.getAccountList() thread running...");
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400487 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400488 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400489 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400490 }
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400491 StringVect swigvect = (StringVect) runInstance.getVal();
492
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400493 ArrayList<String> nativelist = new ArrayList<String>();
Alexandre Savard52a72522012-09-27 16:40:13 -0400494
alision371b77e2013-04-23 14:51:26 -0400495 for (int i = 0; i < swigvect.size(); i++)
496 nativelist.add(swigvect.get(i));
Alexandre Savard52a72522012-09-27 16:40:13 -0400497
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400498 return nativelist;
alision371b77e2013-04-23 14:51:26 -0400499 }
Alexandre Lision4b4233a2013-10-16 17:24:17 -0400500
Alexandre Lision4cf78702013-10-16 13:43:23 -0400501 @Override
Alexandre Lision4b4233a2013-10-16 17:24:17 -0400502 public void setAccountOrder(final String order) {
Alexandre Lision4cf78702013-10-16 13:43:23 -0400503 getExecutor().execute(new SipRunnable() {
504 @Override
505 protected void doRun() throws SameThreadException {
506 Log.i(TAG, "SipService.setAccountsOrder() thread running...");
507 configurationManagerJNI.setAccountsOrder(order);
508 }
509 });
510 }
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400511
512 @Override
alision371b77e2013-04-23 14:51:26 -0400513 public HashMap<String, String> getAccountDetails(final String accountID) {
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400514 class AccountDetails extends SipRunnableWithReturn {
515 private String id;
alision371b77e2013-04-23 14:51:26 -0400516
517 AccountDetails(String accountId) {
518 id = accountId;
519 }
520
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400521 @Override
522 protected StringMap doRun() throws SameThreadException {
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400523 Log.i(TAG, "SipService.getAccountDetails() thread running...");
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400524 return configurationManagerJNI.getAccountDetails(id);
525 }
alision371b77e2013-04-23 14:51:26 -0400526 }
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400527
528 AccountDetails runInstance = new AccountDetails(accountID);
529 getExecutor().execute(runInstance);
alisionfde875f2013-05-28 17:01:54 -0400530
alision371b77e2013-04-23 14:51:26 -0400531 while (!runInstance.isDone()) {
532 }
533 StringMap swigmap = (StringMap) runInstance.getVal();
Alexandre Savard713a34d2012-09-26 15:50:41 -0400534
Alexandre Savard3bbb4792012-10-05 11:30:01 -0400535 HashMap<String, String> nativemap = AccountDetailsHandler.convertSwigToNative(swigmap);
Alexandre Savard713a34d2012-09-26 15:50:41 -0400536
537 return nativemap;
538 }
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400539
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400540 @SuppressWarnings("unchecked")
541 // Hashmap runtime cast
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400542 @Override
alisioncc7bb422013-06-06 15:31:39 -0400543 public void setAccountDetails(final String accountId, final Map map) {
alision371b77e2013-04-23 14:51:26 -0400544 HashMap<String, String> nativemap = (HashMap<String, String>) map;
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400545
Alexandre Savard3bbb4792012-10-05 11:30:01 -0400546 final StringMap swigmap = AccountDetailsHandler.convertFromNativeToSwig(nativemap);
Alexandre Savard718d49f2012-10-02 15:17:13 -0400547
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400548 getExecutor().execute(new SipRunnable() {
549 @Override
550 protected void doRun() throws SameThreadException {
alisioncc7bb422013-06-06 15:31:39 -0400551
552 configurationManagerJNI.setCredentials(accountId, extractCredentials(map));
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400553 configurationManagerJNI.setAccountDetails(accountId, swigmap);
alisioncc7bb422013-06-06 15:31:39 -0400554
Alexandre Lisionafd40e42013-10-15 13:48:37 -0400555 // convertSwigToNative(configurationManagerJNI.getCredentials(accountId));
alisioncc7bb422013-06-06 15:31:39 -0400556 Log.i(TAG, "SipService.setAccountDetails() thread running...");
557 }
558
559 private VectMap extractCredentials(Map map) {
560 VectMap swigmap = new VectMap();
561 StringMap entry = new StringMap();
alision5cfc35d2013-07-11 15:11:39 -0400562 entry.set(AccountDetailBasic.CONFIG_ACCOUNT_USERNAME, (String) map.get(AccountDetailBasic.CONFIG_ACCOUNT_USERNAME));
563 if ((String) map.get(AccountDetailBasic.CONFIG_ACCOUNT_REALM) != null)
564 entry.set(AccountDetailBasic.CONFIG_ACCOUNT_REALM, (String) map.get(AccountDetailBasic.CONFIG_ACCOUNT_REALM));
alisioncc7bb422013-06-06 15:31:39 -0400565 else
alision5cfc35d2013-07-11 15:11:39 -0400566 entry.set(AccountDetailBasic.CONFIG_ACCOUNT_REALM, "*");
567 entry.set(AccountDetailBasic.CONFIG_ACCOUNT_PASSWORD, (String) map.get(AccountDetailBasic.CONFIG_ACCOUNT_PASSWORD));
alisioncc7bb422013-06-06 15:31:39 -0400568 swigmap.add(entry);
569 return swigmap;
570
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400571 }
572 });
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400573 }
574
Alexandre Lisionafd40e42013-10-15 13:48:37 -0400575 // public ArrayList<HashMap<String, String>> convertSwigToNative(VectMap swigmap) {
576 //
577 // ArrayList<HashMap<String, String>> nativemap = new ArrayList<HashMap<String, String>>();
578 // Log.i(TAG, "swigmap size " + swigmap.size());
579 // for (int i = 0; i < swigmap.size(); ++i) {
580 // Log.i(TAG, "Entry " + i);
581 // StringMap tmp = swigmap.get(i);
582 // Log.i(TAG, tmp.get(AccountDetailBasic.CONFIG_ACCOUNT_USERNAME));
583 // // Log.i(TAG, tmp.get(ServiceConstants.CONFIG_ACCOUNT_REALM));
584 // Log.i(TAG, tmp.get(AccountDetailBasic.CONFIG_ACCOUNT_PASSWORD));
585 // }
586 //
587 // return nativemap;
588 // }
alisioncc7bb422013-06-06 15:31:39 -0400589
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400590 @SuppressWarnings("unchecked")
591 // Hashmap runtime cast
Alexandre Savard46036572012-10-05 13:56:49 -0400592 @Override
593 public String addAccount(Map map) {
594 class AddAccount extends SipRunnableWithReturn {
595 StringMap map;
alision371b77e2013-04-23 14:51:26 -0400596
597 AddAccount(StringMap m) {
598 map = m;
599 }
600
Alexandre Savard46036572012-10-05 13:56:49 -0400601 @Override
602 protected String doRun() throws SameThreadException {
603 Log.i(TAG, "SipService.getAccountDetails() thread running...");
604 return configurationManagerJNI.addAccount(map);
605 }
alision371b77e2013-04-23 14:51:26 -0400606 }
Alexandre Savard46036572012-10-05 13:56:49 -0400607
alision371b77e2013-04-23 14:51:26 -0400608 final StringMap swigmap = AccountDetailsHandler.convertFromNativeToSwig((HashMap<String, String>) map);
Alexandre Savard46036572012-10-05 13:56:49 -0400609
610 AddAccount runInstance = new AddAccount(swigmap);
611 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400612 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400613 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400614 }
Alexandre Savard46036572012-10-05 13:56:49 -0400615 String accountId = (String) runInstance.getVal();
616
617 return accountId;
618 }
619
620 @Override
621 public void removeAccount(final String accountId) {
622 getExecutor().execute(new SipRunnable() {
623 @Override
624 protected void doRun() throws SameThreadException {
625 Log.i(TAG, "SipService.setAccountDetails() thread running...");
626 configurationManagerJNI.removeAccount(accountId);
627 }
628 });
629 }
alision5f899632013-04-22 17:26:56 -0400630
alisione2a38e12013-04-25 14:20:20 -0400631 @Override
632 public ArrayList<HashMap<String, String>> getHistory() throws RemoteException {
633 class History extends SipRunnableWithReturn {
634
635 @Override
636 protected VectMap doRun() throws SameThreadException {
637 Log.i(TAG, "SipService.getHistory() thread running...");
alision7f18fc82013-05-01 09:37:33 -0400638
alisione2a38e12013-04-25 14:20:20 -0400639 return configurationManagerJNI.getHistory();
640 }
641 }
642
643 History runInstance = new History();
644 getExecutor().execute(runInstance);
645 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400646 // Log.w(TAG, "Waiting for getHistory");
alisione2a38e12013-04-25 14:20:20 -0400647 }
alision1005ba12013-06-19 13:52:44 -0400648 Log.i(TAG, "SipService.getHistory() DONE");
alisione2a38e12013-04-25 14:20:20 -0400649 VectMap swigmap = (VectMap) runInstance.getVal();
650
651 ArrayList<HashMap<String, String>> nativemap = HistoryHandler.convertSwigToNative(swigmap);
652
653 return nativemap;
654 }
alision7f18fc82013-05-01 09:37:33 -0400655
alision43a9b362013-05-01 16:30:15 -0400656 /*************************
657 * Transfer related API
658 *************************/
659
alision7f18fc82013-05-01 09:37:33 -0400660 @Override
661 public void transfer(final String callID, final String to) throws RemoteException {
662 getExecutor().execute(new SipRunnable() {
663 @Override
664 protected void doRun() throws SameThreadException, RemoteException {
665 Log.i(TAG, "SipService.transfer() thread running...");
666 if (callManagerJNI.transfer(callID, to)) {
667 Bundle bundle = new Bundle();
668 bundle.putString("CallID", callID);
669 bundle.putString("State", "HUNGUP");
670 Intent intent = new Intent(CallManagerCallBack.CALL_STATE_CHANGED);
alision7f18fc82013-05-01 09:37:33 -0400671 intent.putExtra("com.savoirfairelinux.sflphone.service.newstate", bundle);
alision84813a12013-05-27 17:40:39 -0400672 sendBroadcast(intent);
alision7f18fc82013-05-01 09:37:33 -0400673 } else
674 Log.i(TAG, "NOT OK");
675 }
676 });
677
678 }
alision43a9b362013-05-01 16:30:15 -0400679
alision7f18fc82013-05-01 09:37:33 -0400680 @Override
681 public void attendedTransfer(final String transferID, final String targetID) throws RemoteException {
682 getExecutor().execute(new SipRunnable() {
683 @Override
684 protected void doRun() throws SameThreadException, RemoteException {
alision43a9b362013-05-01 16:30:15 -0400685 Log.i(TAG, "SipService.attendedTransfer() thread running...");
alision7f18fc82013-05-01 09:37:33 -0400686 if (callManagerJNI.attendedTransfer(transferID, targetID)) {
687 Log.i(TAG, "OK");
alision7f18fc82013-05-01 09:37:33 -0400688 } else
689 Log.i(TAG, "NOT OK");
690 }
691 });
alision43a9b362013-05-01 16:30:15 -0400692
693 }
694
695 /*************************
696 * Conference related API
697 *************************/
698
699 @Override
700 public void removeConference(final String confID) throws RemoteException {
701 getExecutor().execute(new SipRunnable() {
702 @Override
703 protected void doRun() throws SameThreadException, RemoteException {
704 Log.i(TAG, "SipService.createConference() thread running...");
705 callManagerJNI.removeConference(confID);
706 }
707 });
708
alision7f18fc82013-05-01 09:37:33 -0400709 }
710
711 @Override
alision43a9b362013-05-01 16:30:15 -0400712 public void joinParticipant(final String sel_callID, final String drag_callID) throws RemoteException {
713 getExecutor().execute(new SipRunnable() {
714 @Override
715 protected void doRun() throws SameThreadException, RemoteException {
716 Log.i(TAG, "SipService.joinParticipant() thread running...");
717 callManagerJNI.joinParticipant(sel_callID, drag_callID);
alision806e18e2013-06-21 15:30:17 -0400718 // Generate a CONF_CREATED callback
alision43a9b362013-05-01 16:30:15 -0400719 }
720 });
721
alision7f18fc82013-05-01 09:37:33 -0400722 }
723
alision7f18fc82013-05-01 09:37:33 -0400724 @Override
alision806e18e2013-06-21 15:30:17 -0400725 public void addParticipant(final SipCall call, final String confID) throws RemoteException {
alision43a9b362013-05-01 16:30:15 -0400726 getExecutor().execute(new SipRunnable() {
727 @Override
728 protected void doRun() throws SameThreadException, RemoteException {
729 Log.i(TAG, "SipService.addParticipant() thread running...");
alision806e18e2013-06-21 15:30:17 -0400730 callManagerJNI.addParticipant(call.getCallId(), confID);
731 current_confs.get(confID).getParticipants().add(call);
alision43a9b362013-05-01 16:30:15 -0400732 }
733 });
734
alision7f18fc82013-05-01 09:37:33 -0400735 }
736
737 @Override
alision43a9b362013-05-01 16:30:15 -0400738 public void addMainParticipant(final String confID) throws RemoteException {
739 getExecutor().execute(new SipRunnable() {
740 @Override
741 protected void doRun() throws SameThreadException, RemoteException {
742 Log.i(TAG, "SipService.addMainParticipant() thread running...");
743 callManagerJNI.addMainParticipant(confID);
744 }
745 });
746
alision7f18fc82013-05-01 09:37:33 -0400747 }
748
749 @Override
alision43a9b362013-05-01 16:30:15 -0400750 public void detachParticipant(final String callID) throws RemoteException {
751 getExecutor().execute(new SipRunnable() {
752 @Override
753 protected void doRun() throws SameThreadException, RemoteException {
754 Log.i(TAG, "SipService.detachParticipant() thread running...");
alision806e18e2013-06-21 15:30:17 -0400755 Log.i(TAG, "Detaching " + callID);
756 Iterator<Entry<String, Conference>> it = current_confs.entrySet().iterator();
757 Log.i(TAG, "current_confs size " + current_confs.size());
758 while (it.hasNext()) {
759 Conference tmp = it.next().getValue();
760 Log.i(TAG, "conf has " + tmp.getParticipants().size() + " participants");
761 if (tmp.contains(callID)) {
762 current_calls.put(callID, tmp.getCall(callID));
763 Log.i(TAG, "Call found and put in current_calls");
764 }
765 }
alision43a9b362013-05-01 16:30:15 -0400766 callManagerJNI.detachParticipant(callID);
767 }
768 });
769
alision7f18fc82013-05-01 09:37:33 -0400770 }
771
772 @Override
alision43a9b362013-05-01 16:30:15 -0400773 public void joinConference(final String sel_confID, final String drag_confID) throws RemoteException {
774 getExecutor().execute(new SipRunnable() {
775 @Override
776 protected void doRun() throws SameThreadException, RemoteException {
777 Log.i(TAG, "SipService.joinConference() thread running...");
778 callManagerJNI.joinConference(sel_confID, drag_confID);
779 }
780 });
781
alision7f18fc82013-05-01 09:37:33 -0400782 }
783
784 @Override
alision43a9b362013-05-01 16:30:15 -0400785 public void hangUpConference(final String confID) throws RemoteException {
786 getExecutor().execute(new SipRunnable() {
787 @Override
788 protected void doRun() throws SameThreadException, RemoteException {
789 Log.i(TAG, "SipService.joinConference() thread running...");
790 callManagerJNI.hangUpConference(confID);
791 }
792 });
793
alision7f18fc82013-05-01 09:37:33 -0400794 }
795
796 @Override
alision43a9b362013-05-01 16:30:15 -0400797 public void holdConference(final String confID) throws RemoteException {
798 getExecutor().execute(new SipRunnable() {
799 @Override
800 protected void doRun() throws SameThreadException, RemoteException {
801 Log.i(TAG, "SipService.holdConference() thread running...");
802 callManagerJNI.holdConference(confID);
803 }
804 });
805
alision7f18fc82013-05-01 09:37:33 -0400806 }
807
808 @Override
alision43a9b362013-05-01 16:30:15 -0400809 public void unholdConference(final String confID) throws RemoteException {
810 getExecutor().execute(new SipRunnable() {
811 @Override
812 protected void doRun() throws SameThreadException, RemoteException {
813 Log.i(TAG, "SipService.unholdConference() thread running...");
814 callManagerJNI.unholdConference(confID);
815 }
816 });
817
alision7f18fc82013-05-01 09:37:33 -0400818 }
Alexandre Lision67817192013-07-18 12:04:30 -0400819
alisioncd8fb912013-06-28 14:43:51 -0400820 @Override
821 public boolean isConferenceParticipant(final String callID) throws RemoteException {
822 class IsParticipant extends SipRunnableWithReturn {
823
824 @Override
825 protected Boolean doRun() throws SameThreadException {
826 Log.i(TAG, "SipService.isRecording() thread running...");
827 return callManagerJNI.isConferenceParticipant(callID);
828 }
829 }
830
831 IsParticipant runInstance = new IsParticipant();
832 getExecutor().execute(runInstance);
833 while (!runInstance.isDone()) {
834 }
835
836 return (Boolean) runInstance.getVal();
837 }
alision7f18fc82013-05-01 09:37:33 -0400838
839 @Override
alisiondf1dac92013-06-27 17:35:53 -0400840 public HashMap<String, Conference> getConferenceList() throws RemoteException {
Alexandre Lision67817192013-07-18 12:04:30 -0400841 // class ConfList extends SipRunnableWithReturn {
842 // @Override
843 // protected StringVect doRun() throws SameThreadException {
844 // Log.i(TAG, "SipService.getConferenceList() thread running...");
845 // return callManagerJNI.getConferenceList();
846 // }
847 // }
848 // ;
849 // ConfList runInstance = new ConfList();
850 // getExecutor().execute(runInstance);
851 // while (!runInstance.isDone()) {
852 // // Log.w(TAG, "Waiting for getConferenceList");
853 // }
854 // StringVect swigvect = (StringVect) runInstance.getVal();
855 //
856 // ArrayList<String> nativelist = new ArrayList<String>();
857 //
858 // for (int i = 0; i < swigvect.size(); i++)
859 // nativelist.add(swigvect.get(i));
860 //
861 // return nativelist;
alisiondf1dac92013-06-27 17:35:53 -0400862 return current_confs;
alision7f18fc82013-05-01 09:37:33 -0400863 }
864
865 @Override
alision907bde72013-06-20 14:40:37 -0400866 public List getParticipantList(final String confID) throws RemoteException {
867 class PartList extends SipRunnableWithReturn {
868 @Override
869 protected StringVect doRun() throws SameThreadException {
870 Log.i(TAG, "SipService.getAccountList() thread running...");
871 return callManagerJNI.getParticipantList(confID);
872 }
873 }
874 ;
875 PartList runInstance = new PartList();
876 getExecutor().execute(runInstance);
877 while (!runInstance.isDone()) {
878 // Log.w(TAG, "Waiting for getConferenceList");
879 }
880 StringVect swigvect = (StringVect) runInstance.getVal();
881
882 ArrayList<String> nativelist = new ArrayList<String>();
883
884 for (int i = 0; i < swigvect.size(); i++)
885 nativelist.add(swigvect.get(i));
886
887 return nativelist;
alision7f18fc82013-05-01 09:37:33 -0400888 }
alision806e18e2013-06-21 15:30:17 -0400889
alision1005ba12013-06-19 13:52:44 -0400890 @Override
alision7f18fc82013-05-01 09:37:33 -0400891 public String getConferenceId(String callID) throws RemoteException {
alision43a9b362013-05-01 16:30:15 -0400892 Log.e(TAG, "getConferenceList not implemented");
alision7f18fc82013-05-01 09:37:33 -0400893 return null;
894 }
895
896 @Override
alision806e18e2013-06-21 15:30:17 -0400897 public String getConferenceDetails(final String callID) throws RemoteException {
898 class ConfDetails extends SipRunnableWithReturn {
899 @Override
900 protected StringMap doRun() throws SameThreadException {
901 Log.i(TAG, "SipService.getAccountList() thread running...");
902 return callManagerJNI.getConferenceDetails(callID);
903 }
904 }
905 ;
906 ConfDetails runInstance = new ConfDetails();
907 getExecutor().execute(runInstance);
908 while (!runInstance.isDone()) {
909 // Log.w(TAG, "Waiting for getConferenceList");
910 }
911 StringMap swigvect = (StringMap) runInstance.getVal();
912
913 return swigvect.get("CONF_STATE");
alision7f18fc82013-05-01 09:37:33 -0400914 }
915
alision04a00182013-05-10 17:05:29 -0400916 @Override
917 public String getRecordPath() throws RemoteException {
918 class RecordPath extends SipRunnableWithReturn {
919
920 @Override
921 protected String doRun() throws SameThreadException {
922 Log.i(TAG, "SipService.getRecordPath() thread running...");
Adrien Béraud9360f242013-09-19 11:07:42 +1000923 return configurationManagerJNI.getRecordPath();
alision04a00182013-05-10 17:05:29 -0400924 }
925 }
926
927 RecordPath runInstance = new RecordPath();
928 getExecutor().execute(runInstance);
929 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400930 // Log.w(TAG, "Waiting for getRecordPath");
alision04a00182013-05-10 17:05:29 -0400931 }
932 String path = (String) runInstance.getVal();
933
934 return path;
935 }
936
937 @Override
Alexandre Lisiona764c682013-09-09 10:02:07 -0400938 public boolean toggleRecordingCall(final String id) throws RemoteException {
Adrien Béraud9360f242013-09-19 11:07:42 +1000939
Alexandre Lisiona764c682013-09-09 10:02:07 -0400940 class ToggleRecording extends SipRunnableWithReturn {
941
alision04a00182013-05-10 17:05:29 -0400942 @Override
Alexandre Lisiona764c682013-09-09 10:02:07 -0400943 protected Boolean doRun() throws SameThreadException {
944 Log.i(TAG, "SipService.toggleRecordingCall() thread running...");
945 return callManagerJNI.toggleRecording(id);
alision04a00182013-05-10 17:05:29 -0400946 }
Alexandre Lisiona764c682013-09-09 10:02:07 -0400947 }
948
949 ToggleRecording runInstance = new ToggleRecording();
950 getExecutor().execute(runInstance);
951 while (!runInstance.isDone()) {
952 }
953
954 return (Boolean) runInstance.getVal();
alision04a00182013-05-10 17:05:29 -0400955
956 }
Alexandre Lision67817192013-07-18 12:04:30 -0400957
alision50fa0722013-06-25 17:29:44 -0400958 @Override
alisiondf1dac92013-06-27 17:35:53 -0400959 public boolean isRecording(final String id) throws RemoteException {
960 class IsRecording extends SipRunnableWithReturn {
961
962 @Override
963 protected Boolean doRun() throws SameThreadException {
964 Log.i(TAG, "SipService.isRecording() thread running...");
965 return callManagerJNI.getIsRecording(id);
966 }
967 }
968
969 IsRecording runInstance = new IsRecording();
970 getExecutor().execute(runInstance);
971 while (!runInstance.isDone()) {
972 }
973
974 return (Boolean) runInstance.getVal();
Alexandre Lision67817192013-07-18 12:04:30 -0400975
alisiondf1dac92013-06-27 17:35:53 -0400976 }
Alexandre Lision67817192013-07-18 12:04:30 -0400977
alisiondf1dac92013-06-27 17:35:53 -0400978 @Override
alision50fa0722013-06-25 17:29:44 -0400979 public boolean startRecordedFilePlayback(final String filepath) throws RemoteException {
980 getExecutor().execute(new SipRunnable() {
981 @Override
982 protected void doRun() throws SameThreadException, RemoteException {
983 Log.i(TAG, "SipService.setRecordingCall() thread running...");
984 callManagerJNI.startRecordedFilePlayback(filepath);
985 }
986 });
987 return false;
988 }
989
990 @Override
991 public void stopRecordedFilePlayback(final String filepath) throws RemoteException {
992 getExecutor().execute(new SipRunnable() {
993 @Override
994 protected void doRun() throws SameThreadException, RemoteException {
995 Log.i(TAG, "SipService.stopRecordedFilePlayback() thread running...");
996 callManagerJNI.stopRecordedFilePlayback(filepath);
997 }
998 });
999 }
alision04a00182013-05-10 17:05:29 -04001000
1001 @Override
1002 public void setRecordPath(final String path) throws RemoteException {
1003 getExecutor().execute(new SipRunnable() {
1004 @Override
1005 protected void doRun() throws SameThreadException, RemoteException {
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001006 Log.i(TAG, "SipService.setRecordPath() " + path + " thread running...");
Adrien Béraud9360f242013-09-19 11:07:42 +10001007 configurationManagerJNI.setRecordPath(path);
alision04a00182013-05-10 17:05:29 -04001008 }
1009 });
1010 }
1011
1012 @Override
1013 public void sendTextMessage(final String callID, final String message, final String from) throws RemoteException {
1014 getExecutor().execute(new SipRunnable() {
1015 @Override
1016 protected void doRun() throws SameThreadException, RemoteException {
1017 Log.i(TAG, "SipService.sendTextMessage() thread running...");
Alexandre Lision10314352013-07-17 15:06:56 -04001018 callManagerJNI.sendTextMessage(callID, message);
alision04a00182013-05-10 17:05:29 -04001019 }
1020 });
1021
1022 }
1023
alisiond295ec22013-05-17 10:12:13 -04001024 @Override
Alexandre Lision4cf78702013-10-16 13:43:23 -04001025 public List getAudioCodecList(final String accountID) throws RemoteException {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001026 class AudioCodecList extends SipRunnableWithReturn {
1027
1028 @Override
Alexandre Lision933ef0a2013-10-15 17:28:40 -04001029 protected ArrayList<Codec> doRun() throws SameThreadException {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001030 Log.i(TAG, "SipService.getAudioCodecList() thread running...");
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001031 ArrayList<Codec> results = new ArrayList<Codec>();
Alexandre Lision4cf78702013-10-16 13:43:23 -04001032
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001033 IntVect active_payloads = configurationManagerJNI.getActiveAudioCodecList(accountID);
1034 for (int i = 0; i < active_payloads.size(); ++i) {
1035
Alexandre Lision039a3cf2013-10-16 17:44:57 -04001036 results.add(new Codec(active_payloads.get(i), configurationManagerJNI.getAudioCodecDetails(active_payloads.get(i)), true));
Alexandre Lisione0045442013-10-25 09:16:19 -04001037
Alexandre Lision4cf78702013-10-16 13:43:23 -04001038 }
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001039
Alexandre Lision039a3cf2013-10-16 17:44:57 -04001040 // if (results.get(active_payloads.get(i)) != null) {
1041 // results.get(active_payloads.get(i)).setEnabled(true);
1042
1043 IntVect payloads = configurationManagerJNI.getAudioCodecList();
1044
1045 for (int i = 0; i < payloads.size(); ++i) {
1046 boolean isActive = false;
1047 for (Codec co : results) {
1048 if (co.getPayload().toString().contentEquals(String.valueOf(payloads.get(i))))
1049 isActive = true;
1050
1051 }
1052 if (isActive)
1053 continue;
1054 else
1055 results.add(new Codec(payloads.get(i), configurationManagerJNI.getAudioCodecDetails(payloads.get(i)), false));
1056
1057 }
1058
1059 // if (!results.containsKey(payloads.get(i))) {
1060 // results.put(payloads.get(i), new Codec(payloads.get(i), configurationManagerJNI.getAudioCodecDetails(payloads.get(i)), false));
1061 // Log.i(TAG, "Other, Adding:" + results.get((payloads.get(i))).getName());
1062 // }
1063
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001064 return results;
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001065 }
1066 }
1067
1068 AudioCodecList runInstance = new AudioCodecList();
1069 getExecutor().execute(runInstance);
1070 while (!runInstance.isDone()) {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001071 }
Alexandre Lision933ef0a2013-10-15 17:28:40 -04001072 ArrayList<Codec> codecs = (ArrayList<Codec>) runInstance.getVal();
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001073 return codecs;
alisiond295ec22013-05-17 10:12:13 -04001074 }
1075
alision9f7a6ec2013-05-24 16:26:26 -04001076 @Override
Alexandre Lision4cf78702013-10-16 13:43:23 -04001077 public Map getRingtoneList() throws RemoteException {
1078 class RingtoneList extends SipRunnableWithReturn {
1079
1080 @Override
1081 protected StringMap doRun() throws SameThreadException {
1082 Log.i(TAG, "SipService.getRingtoneList() thread running...");
1083 return configurationManagerJNI.getRingtoneList();
1084 }
1085 }
1086
1087 RingtoneList runInstance = new RingtoneList();
1088 getExecutor().execute(runInstance);
1089 while (!runInstance.isDone()) {
1090 }
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001091 StringMap ringtones = (StringMap) runInstance.getVal();
1092
1093 for (int i = 0; i < ringtones.size(); ++i) {
1094 // Log.i(TAG,"ringtones "+i+" "+ ringtones.);
1095 }
1096
Alexandre Lision4cf78702013-10-16 13:43:23 -04001097 return null;
1098 }
1099
1100 @Override
1101 public void setActiveCodecList(final List codecs, final String accountID) throws RemoteException {
1102 getExecutor().execute(new SipRunnable() {
1103 @Override
1104 protected void doRun() throws SameThreadException, RemoteException {
1105 Log.i(TAG, "SipService.setActiveAudioCodecList() thread running...");
1106 StringVect list = new StringVect();
1107 for (int i = 0; i < codecs.size(); ++i) {
1108 list.add((String) codecs.get(i));
1109 }
1110 configurationManagerJNI.setActiveAudioCodecList(list, accountID);
1111 }
1112 });
1113 }
1114
1115 @Override
alisionfde875f2013-05-28 17:01:54 -04001116 public HashMap<String, SipCall> getCallList() throws RemoteException {
alision85704182013-05-29 15:23:03 -04001117 // class CallList extends SipRunnableWithReturn {
1118 //
1119 // @Override
1120 // protected StringVect doRun() throws SameThreadException {
1121 // Log.i(TAG, "SipService.getCallList() thread running...");
1122 // return callManagerJNI.getCallList();
1123 // }
1124 // }
1125 //
1126 // CallList runInstance = new CallList();
1127 // getExecutor().execute(runInstance);
1128 // while (!runInstance.isDone()) {
1129 // Log.w(TAG, "Waiting for getAudioCodecList");
1130 // }
1131 // StringVect swigmap = (StringVect) runInstance.getVal();
1132 //
1133 // ArrayList<String> nativemap = new ArrayList<String>();
1134 // for (int i = 0; i < swigmap.size(); ++i) {
1135 //
1136 // String t = swigmap.get(i);
1137 // nativemap.add(t);
1138 // }
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001139 // if(callManagerJNI == null)
1140 // return new HashMap<String, SipCall>();
1141 //
1142 //
1143 // HashMap<String, SipCall> results = new HashMap<String, SipCall>();
1144 // StringVect calls = callManagerJNI.getCallList();
1145 // for(int i = 0 ; i < calls.size(); ++i){
1146 // results.put(calls.get(i), new SipCall(calls.get(i), callManagerJNI.getCallDetails(calls.get(i))));
1147 // }
alision9f7a6ec2013-05-24 16:26:26 -04001148
alision2cb99562013-05-30 17:02:20 -04001149 return getCurrent_calls();
alision9f7a6ec2013-05-24 16:26:26 -04001150 }
1151
alision85704182013-05-29 15:23:03 -04001152 @Override
1153 public SipCall getCall(String callID) throws RemoteException {
alision2cb99562013-05-30 17:02:20 -04001154 return getCurrent_calls().get(callID);
1155 }
1156
1157 /***********************
1158 * Notification API
1159 ***********************/
1160 @Override
1161 public void createNotification() throws RemoteException {
1162 makeNotification();
alisioncc7bb422013-06-06 15:31:39 -04001163
alision2cb99562013-05-30 17:02:20 -04001164 }
1165
1166 @Override
1167 public void destroyNotification() throws RemoteException {
1168 removeNotification();
alisioncc7bb422013-06-06 15:31:39 -04001169
alision2cb99562013-05-30 17:02:20 -04001170 }
alisioncc7bb422013-06-06 15:31:39 -04001171
Adrien Béraud9360f242013-09-19 11:07:42 +10001172 private final int NOTIFICATION_ID = new Random().nextInt(1000);
alisioncc7bb422013-06-06 15:31:39 -04001173
alision2cb99562013-05-30 17:02:20 -04001174 private void makeNotification() {
alisioncc7bb422013-06-06 15:31:39 -04001175 if (current_calls.size() == 0) {
alision2cb99562013-05-30 17:02:20 -04001176 return;
1177 }
1178 Intent notificationIntent = new Intent(getApplicationContext(), SFLPhoneHomeActivity.class);
alisioncc7bb422013-06-06 15:31:39 -04001179 PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 007, notificationIntent,
1180 PendingIntent.FLAG_UPDATE_CURRENT);
alision2cb99562013-05-30 17:02:20 -04001181
1182 NotificationManager nm = (NotificationManager) getBaseContext().getSystemService(Context.NOTIFICATION_SERVICE);
Adrien Béraud9360f242013-09-19 11:07:42 +10001183 nm.cancel(NOTIFICATION_ID); // clear previous notifications.
alision2cb99562013-05-30 17:02:20 -04001184
1185 NotificationCompat.Builder builder = new NotificationCompat.Builder(getBaseContext());
alisioncc7bb422013-06-06 15:31:39 -04001186 //
1187 // builder.setContent(view);
1188 builder.setContentIntent(contentIntent).setOngoing(true).setSmallIcon(R.drawable.ic_launcher)
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001189 .setContentTitle(getCurrent_calls().size() + " ongoing calls").setTicker("Pending calls").setWhen(System.currentTimeMillis())
1190 .setAutoCancel(false);
alision2cb99562013-05-30 17:02:20 -04001191 builder.setPriority(NotificationCompat.PRIORITY_MAX);
1192 Notification n = builder.build();
1193
1194 nm.notify(NOTIFICATION_ID, n);
alision2cb99562013-05-30 17:02:20 -04001195 }
1196
1197 public void removeNotification() {
1198 NotificationManager nm = (NotificationManager) getBaseContext().getSystemService(Context.NOTIFICATION_SERVICE);
1199 nm.cancel(NOTIFICATION_ID);
alision85704182013-05-29 15:23:03 -04001200 }
1201
alisiondf1dac92013-06-27 17:35:53 -04001202 @Override
1203 public Conference getCurrentCall() throws RemoteException {
Alexandre Lision67817192013-07-18 12:04:30 -04001204 for (SipCall i : current_calls.values()) {
Adrien Béraud9360f242013-09-19 11:07:42 +10001205
Alexandre Lisionc51ccb12013-09-11 16:00:30 -04001206 // Incoming >> Ongoing
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001207 if (i.isIncoming()) {
Alexandre Lisionc51ccb12013-09-11 16:00:30 -04001208 Conference tmp = new Conference("-1");
1209 tmp.getParticipants().add(i);
1210 return tmp;
1211 }
Adrien Béraud9360f242013-09-19 11:07:42 +10001212
Alexandre Lision67817192013-07-18 12:04:30 -04001213 if (i.isOngoing()) {
alisiondf1dac92013-06-27 17:35:53 -04001214 Conference tmp = new Conference("-1");
1215 tmp.getParticipants().add(i);
1216 return tmp;
1217 }
1218 }
Alexandre Lision67817192013-07-18 12:04:30 -04001219
1220 if (!current_confs.isEmpty()) {
alisiondf1dac92013-06-27 17:35:53 -04001221 return (Conference) current_confs.values().toArray()[0];
1222 }
1223 return null;
1224 }
1225
Alexandre Lision64dc8c02013-09-25 15:32:25 -04001226 @Override
1227 public void playDtmf(final String key) throws RemoteException {
1228 getExecutor().execute(new SipRunnable() {
1229 @Override
1230 protected void doRun() throws SameThreadException, RemoteException {
1231 Log.i(TAG, "SipService.playDtmf() thread running...");
1232 callManagerJNI.playDTMF(key);
1233 }
1234 });
1235 }
1236
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001237 @Override
1238 public List getConcurrentCalls() throws RemoteException {
1239 ArrayList<Conference> toReturn = new ArrayList<Conference>();
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001240
1241 for (SipCall sip : current_calls.values()) {
1242 if (!sip.isCurrent()) {
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001243 Conference tmp = new Conference("-1");
1244 tmp.getParticipants().add(sip);
1245 toReturn.add(tmp);
1246 }
1247 }
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001248
1249 Log.i(TAG, "toReturn SIZE " + toReturn.size());
1250
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001251 return toReturn;
1252 }
1253
Alexandre Lision4fb22622013-10-21 16:26:33 -04001254 @Override
1255 public String getCurrentAudioCodecName(String callID) throws RemoteException {
1256 return callManagerJNI.getCurrentAudioCodecName(callID);
1257 }
1258
Emeric Vigier6119d782012-09-21 18:04:14 -04001259 };
Alexandre Lision6d867b92013-10-25 15:36:28 -04001260
1261
1262 public void changeVolume(int currentVolume) {
1263// StringVect resultsInput = configurationManagerJNI.getAudioInputDeviceList();
1264// StringVect resultsOutput = configurationManagerJNI.getAudioOutputDeviceList();
1265//
1266// Log.i(TAG, "------------------> INPUT DEVICES");
1267// for(int i = 0 ; i < resultsInput.size(); ++i){
1268// Log.i(TAG, resultsInput.get(i));
1269// }
1270//
1271// Log.i(TAG, "------------------> OUTPUT DEVICES");
1272// for(int i = 0 ; i < resultsOutput.size(); ++i){
1273// Log.i(TAG, resultsOutput.get(i));
1274// }
1275
1276// Log.i(TAG,"AudioManager ------------> "+configurationManagerJNI.getAudioManager());
1277
1278 callManagerJNI.setVolume("speaker", currentVolume);
1279 }
Emeric Vigiereaf2c492012-09-19 14:38:20 -04001280}