blob: 99706920fa1c62f5970450a8ec89d92e8f98ed01 [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;
Alexandre Lisione0045442013-10-25 09:16:19 -040065import android.telephony.TelephonyManager;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040066import android.util.Log;
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 Lision0a300ff2013-09-23 14:22:34 -0400152
153 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);
156 // Toast.makeText(this, "Sflphone Service stopped", Toast.LENGTH_SHORT).show();
alision43a9b362013-05-01 16:30:15 -0400157 super.onDestroy();
158
alision43a9b362013-05-01 16:30:15 -0400159 }
160
161 @Override
162 public IBinder onBind(Intent arg0) {
163 Log.i(TAG, "onBound");
164 return mBinder;
165 }
166
167 private static Looper createLooper() {
168 if (executorThread == null) {
169 Log.d(TAG, "Creating new handler thread");
170 // ADT gives a fake warning due to bad parse rule.
171 executorThread = new HandlerThread("SipService.Executor");
172 executorThread.start();
173 }
174 return executorThread.getLooper();
175 }
176
177 public SipServiceExecutor getExecutor() {
178 // create mExecutor lazily
179 if (mExecutor == null) {
180 mExecutor = new SipServiceExecutor(this);
181 }
182 return mExecutor;
183 }
184
185 // Executes immediate tasks in a single executorThread.
186 public static class SipServiceExecutor extends Handler {
187 WeakReference<SipService> handlerService;
188
189 SipServiceExecutor(SipService s) {
190 super(createLooper());
191 handlerService = new WeakReference<SipService>(s);
192 }
193
194 public void execute(Runnable task) {
195 // TODO: add wakelock
196 Message.obtain(this, 0/* don't care */, task).sendToTarget();
Alexandre Lisioncdec5952013-07-17 14:18:22 -0400197 Log.w(TAG, "SenT!");
alision43a9b362013-05-01 16:30:15 -0400198 }
199
200 @Override
201 public void handleMessage(Message msg) {
202 if (msg.obj instanceof Runnable) {
203 executeInternal((Runnable) msg.obj);
204 } else {
205 Log.w(TAG, "can't handle msg: " + msg);
206 }
207 }
208
209 private void executeInternal(Runnable task) {
210 try {
211 task.run();
212 } catch (Throwable t) {
213 Log.e(TAG, "run task: " + task, t);
214 }
215 }
216 }
217
218 private void startPjSipStack() throws SameThreadException {
219 if (isPjSipStackStarted)
220 return;
221
222 try {
223 System.loadLibrary("gnustl_shared");
224 System.loadLibrary("expat");
225 System.loadLibrary("yaml");
226 System.loadLibrary("ccgnu2");
227 System.loadLibrary("crypto");
228 System.loadLibrary("ssl");
Alexandre Lision7c6f4a62013-09-05 13:27:01 -0400229 System.loadLibrary("sndfile");
alision43a9b362013-05-01 16:30:15 -0400230 System.loadLibrary("ccrtp1");
alision43a9b362013-05-01 16:30:15 -0400231 System.loadLibrary("samplerate");
232 System.loadLibrary("codec_ulaw");
233 System.loadLibrary("codec_alaw");
Alexandre Lision0a300ff2013-09-23 14:22:34 -0400234 System.loadLibrary("codec_g722");
Alexandre Lision6deda412013-09-25 13:21:22 -0400235 System.loadLibrary("codec_opus");
Alexandre Lisiona1ad1c32013-10-15 16:35:20 -0400236 System.loadLibrary("codec_gsm");
Alexandre Lision62138172013-10-17 11:52:45 -0400237 System.loadLibrary("codec_speex_nb");
238 System.loadLibrary("codec_speex_ub");
239 System.loadLibrary("codec_speex_wb");
alision43a9b362013-05-01 16:30:15 -0400240 System.loadLibrary("speexresampler");
241 System.loadLibrary("sflphone");
242 isPjSipStackStarted = true;
Adrien Béraud9360f242013-09-19 11:07:42 +1000243
alision43a9b362013-05-01 16:30:15 -0400244 } catch (UnsatisfiedLinkError e) {
245 Log.e(TAG, "Problem with the current Pj stack...", e);
246 isPjSipStackStarted = false;
247 return;
248 } catch (Exception e) {
249 Log.e(TAG, "Problem with the current Pj stack...", e);
250 }
251
Alexandre Lision67817192013-07-18 12:04:30 -0400252 Log.i(TAG, "PjSIPStack started");
253 managerImpl = SFLPhoneservice.instance();
254
255 /* set static AppPath before calling manager.init */
256
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400257 // managerImpl.setPath(sflphoneApp.getAppPath());
alision43a9b362013-05-01 16:30:15 -0400258
alision3ea8f3c2013-07-16 17:35:35 -0400259 callManagerJNI = new CallManager();
alision43a9b362013-05-01 16:30:15 -0400260 callManagerCallBack = new CallManagerCallBack(this);
261 SFLPhoneservice.setCallbackObject(callManagerCallBack);
262
alision3ea8f3c2013-07-16 17:35:35 -0400263 configurationManagerJNI = new ConfigurationManager();
alision43a9b362013-05-01 16:30:15 -0400264 configurationManagerCallback = new ConfigurationManagerCallback(this);
265 SFLPhoneservice.setConfigurationCallbackObject(configurationManagerCallback);
Adrien Béraud9360f242013-09-19 11:07:42 +1000266
Alexandre Lision67817192013-07-18 12:04:30 -0400267 Log.i(TAG, "before init");
268 managerImpl.init("");
Adrien Béraud9360f242013-09-19 11:07:42 +1000269
Alexandre Lision67817192013-07-18 12:04:30 -0400270 Log.i(TAG, "->startPjSipStack");
alision43a9b362013-05-01 16:30:15 -0400271
alision43a9b362013-05-01 16:30:15 -0400272 }
273
Adrien Béraud9360f242013-09-19 11:07:42 +1000274 public HashMap<String, SipCall> getCurrent_calls() {
alision2cb99562013-05-30 17:02:20 -0400275 return current_calls;
276 }
277
alision43a9b362013-05-01 16:30:15 -0400278 // Enforce same thread contract to ensure we do not call from somewhere else
279 public class SameThreadException extends Exception {
280 private static final long serialVersionUID = -905639124232613768L;
281
282 public SameThreadException() {
283 super("Should be launched from a single worker thread");
284 }
285 }
286
287 public abstract static class SipRunnable implements Runnable {
288 protected abstract void doRun() throws SameThreadException, RemoteException;
289
Adrien Béraud9360f242013-09-19 11:07:42 +1000290 @Override
alision43a9b362013-05-01 16:30:15 -0400291 public void run() {
292 try {
293 doRun();
294 } catch (SameThreadException e) {
295 Log.e(TAG, "Not done from same thread");
296 } catch (RemoteException e) {
297 Log.e(TAG, e.toString());
298 }
299 }
300 }
301
302 public abstract static class SipRunnableWithReturn implements Runnable {
303 Object obj = null;
304 boolean done = false;
305
306 protected abstract Object doRun() throws SameThreadException;
307
308 public Object getVal() {
309 return obj;
310 }
311
312 public boolean isDone() {
313 return done;
314 }
315
Adrien Béraud9360f242013-09-19 11:07:42 +1000316 @Override
alision43a9b362013-05-01 16:30:15 -0400317 public void run() {
318 try {
319 obj = doRun();
320 done = true;
321 } catch (SameThreadException e) {
322 Log.e(TAG, "Not done from same thread");
323 }
324 }
325 }
326
327 class StartRunnable extends SipRunnable {
328 @Override
329 protected void doRun() throws SameThreadException {
330 startPjSipStack();
331 }
332 }
333
alision43a9b362013-05-01 16:30:15 -0400334 /* ************************************
335 *
336 * Implement public interface for the service
337 *
Alexandre Lision67817192013-07-18 12:04:30 -0400338 * *********************************
339 */
340
Emeric Vigier6119d782012-09-21 18:04:14 -0400341 private final ISipService.Stub mBinder = new ISipService.Stub() {
342
343 @Override
alisionfde875f2013-05-28 17:01:54 -0400344 public void placeCall(final SipCall call) {
Emeric Vigier6119d782012-09-21 18:04:14 -0400345 getExecutor().execute(new SipRunnable() {
346 @Override
347 protected void doRun() throws SameThreadException {
348 Log.i(TAG, "SipService.placeCall() thread running...");
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400349 callManagerJNI.placeCall(call.getAccount().getAccountID(), call.getCallId(), call.getContact().getPhones().get(0).getNumber());
Adrien Béraud9360f242013-09-19 11:07:42 +1000350
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400351 HashMap<String, String> details = CallDetailsHandler.convertSwigToNative(callManagerJNI.getCallDetails(call.getCallId()));
Alexandre Lisionebeb3662013-09-17 16:20:54 -0400352 // watchout timestamp stored by sflphone is in seconds
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400353 call.setTimestamp_start(Long.parseLong(details.get(ServiceConstants.call.TIMESTAMP_START)));
alision2cb99562013-05-30 17:02:20 -0400354 getCurrent_calls().put(call.getCallId(), call);
Adrien Béraud9360f242013-09-19 11:07:42 +1000355
Emeric Vigier6119d782012-09-21 18:04:14 -0400356 }
357 });
358 }
359
360 @Override
361 public void refuse(final String callID) {
362 getExecutor().execute(new SipRunnable() {
363 @Override
364 protected void doRun() throws SameThreadException {
365 Log.i(TAG, "SipService.refuse() thread running...");
366 callManagerJNI.refuse(callID);
367 }
368 });
369 }
370
371 @Override
372 public void accept(final String callID) {
373 getExecutor().execute(new SipRunnable() {
374 @Override
375 protected void doRun() throws SameThreadException {
Tristan Matthews40cf25e2013-07-24 13:45:15 -0400376 Log.i(TAG, "SipService.accept() thread running...");
Emeric Vigier6119d782012-09-21 18:04:14 -0400377 callManagerJNI.accept(callID);
378 }
379 });
380 }
381
382 @Override
383 public void hangUp(final String callID) {
384 getExecutor().execute(new SipRunnable() {
385 @Override
386 protected void doRun() throws SameThreadException {
387 Log.i(TAG, "SipService.hangUp() thread running...");
388 callManagerJNI.hangUp(callID);
389 }
390 });
391 }
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400392
393 @Override
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400394 public void hold(final String callID) {
395 getExecutor().execute(new SipRunnable() {
396 @Override
397 protected void doRun() throws SameThreadException {
398 Log.i(TAG, "SipService.hold() thread running...");
399 callManagerJNI.hold(callID);
400 }
401 });
402 }
403
404 @Override
405 public void unhold(final String callID) {
406 getExecutor().execute(new SipRunnable() {
407 @Override
408 protected void doRun() throws SameThreadException {
409 Log.i(TAG, "SipService.unhold() thread running...");
410 callManagerJNI.unhold(callID);
411 }
412 });
413 }
Adrien Béraud9360f242013-09-19 11:07:42 +1000414
Alexandre Lision6711ab22013-09-16 15:15:38 -0400415 @Override
416 public HashMap<String, String> getCallDetails(String callID) throws RemoteException {
417 class CallDetails extends SipRunnableWithReturn {
418 private String id;
419
420 CallDetails(String callID) {
421 id = callID;
422 }
423
424 @Override
425 protected StringMap doRun() throws SameThreadException {
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400426 Log.i(TAG, "SipService.getCallDetails() thread running...");
Alexandre Lision6711ab22013-09-16 15:15:38 -0400427 return callManagerJNI.getCallDetails(id);
428 }
429 }
430
431 CallDetails runInstance = new CallDetails(callID);
432 getExecutor().execute(runInstance);
433
434 while (!runInstance.isDone()) {
435 }
436 StringMap swigmap = (StringMap) runInstance.getVal();
437
438 HashMap<String, String> nativemap = CallDetailsHandler.convertSwigToNative(swigmap);
439
440 return nativemap;
Adrien Béraud9360f242013-09-19 11:07:42 +1000441
Alexandre Lision6711ab22013-09-16 15:15:38 -0400442 }
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400443
444 @Override
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400445 public void setAudioPlugin(final String audioPlugin) {
446 getExecutor().execute(new SipRunnable() {
alision371b77e2013-04-23 14:51:26 -0400447 @Override
448 protected void doRun() throws SameThreadException {
449 Log.i(TAG, "SipService.setAudioPlugin() thread running...");
450 configurationManagerJNI.setAudioPlugin(audioPlugin);
451 }
Alexandre Savard31d27c62012-10-04 16:05:08 -0400452 });
453 }
454
455 @Override
456 public String getCurrentAudioOutputPlugin() {
457 class CurrentAudioPlugin extends SipRunnableWithReturn {
458 @Override
459 protected String doRun() throws SameThreadException {
460 Log.i(TAG, "SipService.getCurrentAudioOutputPlugin() thread running...");
461 return configurationManagerJNI.getCurrentAudioOutputPlugin();
462 }
alision371b77e2013-04-23 14:51:26 -0400463 }
464 ;
Alexandre Savard31d27c62012-10-04 16:05:08 -0400465
466 CurrentAudioPlugin runInstance = new CurrentAudioPlugin();
467 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400468 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400469 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400470 }
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400471 return (String) runInstance.getVal();
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400472 }
Alexandre Savard713a34d2012-09-26 15:50:41 -0400473
474 @Override
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400475 public ArrayList<String> getAccountList() {
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400476 class AccountList extends SipRunnableWithReturn {
477 @Override
478 protected StringVect doRun() throws SameThreadException {
479 Log.i(TAG, "SipService.getAccountList() thread running...");
480 return configurationManagerJNI.getAccountList();
481 }
alision371b77e2013-04-23 14:51:26 -0400482 }
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400483 AccountList runInstance = new AccountList();
Alexandre Lisioncdec5952013-07-17 14:18:22 -0400484 Log.i(TAG, "SipService.getAccountList() thread running...");
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400485 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400486 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400487 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400488 }
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400489 StringVect swigvect = (StringVect) runInstance.getVal();
490
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400491 ArrayList<String> nativelist = new ArrayList<String>();
Alexandre Savard52a72522012-09-27 16:40:13 -0400492
alision371b77e2013-04-23 14:51:26 -0400493 for (int i = 0; i < swigvect.size(); i++)
494 nativelist.add(swigvect.get(i));
Alexandre Savard52a72522012-09-27 16:40:13 -0400495
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400496 return nativelist;
alision371b77e2013-04-23 14:51:26 -0400497 }
Alexandre Lision4b4233a2013-10-16 17:24:17 -0400498
Alexandre Lision4cf78702013-10-16 13:43:23 -0400499 @Override
Alexandre Lision4b4233a2013-10-16 17:24:17 -0400500 public void setAccountOrder(final String order) {
Alexandre Lision4cf78702013-10-16 13:43:23 -0400501 getExecutor().execute(new SipRunnable() {
502 @Override
503 protected void doRun() throws SameThreadException {
504 Log.i(TAG, "SipService.setAccountsOrder() thread running...");
505 configurationManagerJNI.setAccountsOrder(order);
506 }
507 });
508 }
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400509
510 @Override
alision371b77e2013-04-23 14:51:26 -0400511 public HashMap<String, String> getAccountDetails(final String accountID) {
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400512 class AccountDetails extends SipRunnableWithReturn {
513 private String id;
alision371b77e2013-04-23 14:51:26 -0400514
515 AccountDetails(String accountId) {
516 id = accountId;
517 }
518
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400519 @Override
520 protected StringMap doRun() throws SameThreadException {
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400521 Log.i(TAG, "SipService.getAccountDetails() thread running...");
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400522 return configurationManagerJNI.getAccountDetails(id);
523 }
alision371b77e2013-04-23 14:51:26 -0400524 }
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400525
526 AccountDetails runInstance = new AccountDetails(accountID);
527 getExecutor().execute(runInstance);
alisionfde875f2013-05-28 17:01:54 -0400528
alision371b77e2013-04-23 14:51:26 -0400529 while (!runInstance.isDone()) {
530 }
531 StringMap swigmap = (StringMap) runInstance.getVal();
Alexandre Savard713a34d2012-09-26 15:50:41 -0400532
Alexandre Savard3bbb4792012-10-05 11:30:01 -0400533 HashMap<String, String> nativemap = AccountDetailsHandler.convertSwigToNative(swigmap);
Alexandre Savard713a34d2012-09-26 15:50:41 -0400534
535 return nativemap;
536 }
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400537
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400538 @SuppressWarnings("unchecked")
539 // Hashmap runtime cast
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400540 @Override
alisioncc7bb422013-06-06 15:31:39 -0400541 public void setAccountDetails(final String accountId, final Map map) {
alision371b77e2013-04-23 14:51:26 -0400542 HashMap<String, String> nativemap = (HashMap<String, String>) map;
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400543
Alexandre Savard3bbb4792012-10-05 11:30:01 -0400544 final StringMap swigmap = AccountDetailsHandler.convertFromNativeToSwig(nativemap);
Alexandre Savard718d49f2012-10-02 15:17:13 -0400545
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400546 getExecutor().execute(new SipRunnable() {
547 @Override
548 protected void doRun() throws SameThreadException {
alisioncc7bb422013-06-06 15:31:39 -0400549
550 configurationManagerJNI.setCredentials(accountId, extractCredentials(map));
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400551 configurationManagerJNI.setAccountDetails(accountId, swigmap);
alisioncc7bb422013-06-06 15:31:39 -0400552
Alexandre Lisionafd40e42013-10-15 13:48:37 -0400553 // convertSwigToNative(configurationManagerJNI.getCredentials(accountId));
alisioncc7bb422013-06-06 15:31:39 -0400554 Log.i(TAG, "SipService.setAccountDetails() thread running...");
555 }
556
557 private VectMap extractCredentials(Map map) {
558 VectMap swigmap = new VectMap();
559 StringMap entry = new StringMap();
alision5cfc35d2013-07-11 15:11:39 -0400560 entry.set(AccountDetailBasic.CONFIG_ACCOUNT_USERNAME, (String) map.get(AccountDetailBasic.CONFIG_ACCOUNT_USERNAME));
561 if ((String) map.get(AccountDetailBasic.CONFIG_ACCOUNT_REALM) != null)
562 entry.set(AccountDetailBasic.CONFIG_ACCOUNT_REALM, (String) map.get(AccountDetailBasic.CONFIG_ACCOUNT_REALM));
alisioncc7bb422013-06-06 15:31:39 -0400563 else
alision5cfc35d2013-07-11 15:11:39 -0400564 entry.set(AccountDetailBasic.CONFIG_ACCOUNT_REALM, "*");
565 entry.set(AccountDetailBasic.CONFIG_ACCOUNT_PASSWORD, (String) map.get(AccountDetailBasic.CONFIG_ACCOUNT_PASSWORD));
alisioncc7bb422013-06-06 15:31:39 -0400566 swigmap.add(entry);
567 return swigmap;
568
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400569 }
570 });
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400571 }
572
Alexandre Lisionafd40e42013-10-15 13:48:37 -0400573 // public ArrayList<HashMap<String, String>> convertSwigToNative(VectMap swigmap) {
574 //
575 // ArrayList<HashMap<String, String>> nativemap = new ArrayList<HashMap<String, String>>();
576 // Log.i(TAG, "swigmap size " + swigmap.size());
577 // for (int i = 0; i < swigmap.size(); ++i) {
578 // Log.i(TAG, "Entry " + i);
579 // StringMap tmp = swigmap.get(i);
580 // Log.i(TAG, tmp.get(AccountDetailBasic.CONFIG_ACCOUNT_USERNAME));
581 // // Log.i(TAG, tmp.get(ServiceConstants.CONFIG_ACCOUNT_REALM));
582 // Log.i(TAG, tmp.get(AccountDetailBasic.CONFIG_ACCOUNT_PASSWORD));
583 // }
584 //
585 // return nativemap;
586 // }
alisioncc7bb422013-06-06 15:31:39 -0400587
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400588 @SuppressWarnings("unchecked")
589 // Hashmap runtime cast
Alexandre Savard46036572012-10-05 13:56:49 -0400590 @Override
591 public String addAccount(Map map) {
592 class AddAccount extends SipRunnableWithReturn {
593 StringMap map;
alision371b77e2013-04-23 14:51:26 -0400594
595 AddAccount(StringMap m) {
596 map = m;
597 }
598
Alexandre Savard46036572012-10-05 13:56:49 -0400599 @Override
600 protected String doRun() throws SameThreadException {
601 Log.i(TAG, "SipService.getAccountDetails() thread running...");
602 return configurationManagerJNI.addAccount(map);
603 }
alision371b77e2013-04-23 14:51:26 -0400604 }
Alexandre Savard46036572012-10-05 13:56:49 -0400605
alision371b77e2013-04-23 14:51:26 -0400606 final StringMap swigmap = AccountDetailsHandler.convertFromNativeToSwig((HashMap<String, String>) map);
Alexandre Savard46036572012-10-05 13:56:49 -0400607
608 AddAccount runInstance = new AddAccount(swigmap);
609 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400610 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400611 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400612 }
Alexandre Savard46036572012-10-05 13:56:49 -0400613 String accountId = (String) runInstance.getVal();
614
615 return accountId;
616 }
617
618 @Override
619 public void removeAccount(final String accountId) {
620 getExecutor().execute(new SipRunnable() {
621 @Override
622 protected void doRun() throws SameThreadException {
623 Log.i(TAG, "SipService.setAccountDetails() thread running...");
624 configurationManagerJNI.removeAccount(accountId);
625 }
626 });
627 }
alision5f899632013-04-22 17:26:56 -0400628
alisione2a38e12013-04-25 14:20:20 -0400629 @Override
630 public ArrayList<HashMap<String, String>> getHistory() throws RemoteException {
631 class History extends SipRunnableWithReturn {
632
633 @Override
634 protected VectMap doRun() throws SameThreadException {
635 Log.i(TAG, "SipService.getHistory() thread running...");
alision7f18fc82013-05-01 09:37:33 -0400636
alisione2a38e12013-04-25 14:20:20 -0400637 return configurationManagerJNI.getHistory();
638 }
639 }
640
641 History runInstance = new History();
642 getExecutor().execute(runInstance);
643 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400644 // Log.w(TAG, "Waiting for getHistory");
alisione2a38e12013-04-25 14:20:20 -0400645 }
alision1005ba12013-06-19 13:52:44 -0400646 Log.i(TAG, "SipService.getHistory() DONE");
alisione2a38e12013-04-25 14:20:20 -0400647 VectMap swigmap = (VectMap) runInstance.getVal();
648
649 ArrayList<HashMap<String, String>> nativemap = HistoryHandler.convertSwigToNative(swigmap);
650
651 return nativemap;
652 }
alision7f18fc82013-05-01 09:37:33 -0400653
alision43a9b362013-05-01 16:30:15 -0400654 /*************************
655 * Transfer related API
656 *************************/
657
alision7f18fc82013-05-01 09:37:33 -0400658 @Override
659 public void transfer(final String callID, final String to) throws RemoteException {
660 getExecutor().execute(new SipRunnable() {
661 @Override
662 protected void doRun() throws SameThreadException, RemoteException {
663 Log.i(TAG, "SipService.transfer() thread running...");
664 if (callManagerJNI.transfer(callID, to)) {
665 Bundle bundle = new Bundle();
666 bundle.putString("CallID", callID);
667 bundle.putString("State", "HUNGUP");
668 Intent intent = new Intent(CallManagerCallBack.CALL_STATE_CHANGED);
alision7f18fc82013-05-01 09:37:33 -0400669 intent.putExtra("com.savoirfairelinux.sflphone.service.newstate", bundle);
alision84813a12013-05-27 17:40:39 -0400670 sendBroadcast(intent);
alision7f18fc82013-05-01 09:37:33 -0400671 } else
672 Log.i(TAG, "NOT OK");
673 }
674 });
675
676 }
alision43a9b362013-05-01 16:30:15 -0400677
alision7f18fc82013-05-01 09:37:33 -0400678 @Override
679 public void attendedTransfer(final String transferID, final String targetID) throws RemoteException {
680 getExecutor().execute(new SipRunnable() {
681 @Override
682 protected void doRun() throws SameThreadException, RemoteException {
alision43a9b362013-05-01 16:30:15 -0400683 Log.i(TAG, "SipService.attendedTransfer() thread running...");
alision7f18fc82013-05-01 09:37:33 -0400684 if (callManagerJNI.attendedTransfer(transferID, targetID)) {
685 Log.i(TAG, "OK");
alision7f18fc82013-05-01 09:37:33 -0400686 } else
687 Log.i(TAG, "NOT OK");
688 }
689 });
alision43a9b362013-05-01 16:30:15 -0400690
691 }
692
693 /*************************
694 * Conference related API
695 *************************/
696
697 @Override
698 public void removeConference(final String confID) throws RemoteException {
699 getExecutor().execute(new SipRunnable() {
700 @Override
701 protected void doRun() throws SameThreadException, RemoteException {
702 Log.i(TAG, "SipService.createConference() thread running...");
703 callManagerJNI.removeConference(confID);
704 }
705 });
706
alision7f18fc82013-05-01 09:37:33 -0400707 }
708
709 @Override
alision43a9b362013-05-01 16:30:15 -0400710 public void joinParticipant(final String sel_callID, final String drag_callID) throws RemoteException {
711 getExecutor().execute(new SipRunnable() {
712 @Override
713 protected void doRun() throws SameThreadException, RemoteException {
714 Log.i(TAG, "SipService.joinParticipant() thread running...");
715 callManagerJNI.joinParticipant(sel_callID, drag_callID);
alision806e18e2013-06-21 15:30:17 -0400716 // Generate a CONF_CREATED callback
alision43a9b362013-05-01 16:30:15 -0400717 }
718 });
719
alision7f18fc82013-05-01 09:37:33 -0400720 }
721
alision7f18fc82013-05-01 09:37:33 -0400722 @Override
alision806e18e2013-06-21 15:30:17 -0400723 public void addParticipant(final SipCall call, final String confID) throws RemoteException {
alision43a9b362013-05-01 16:30:15 -0400724 getExecutor().execute(new SipRunnable() {
725 @Override
726 protected void doRun() throws SameThreadException, RemoteException {
727 Log.i(TAG, "SipService.addParticipant() thread running...");
alision806e18e2013-06-21 15:30:17 -0400728 callManagerJNI.addParticipant(call.getCallId(), confID);
729 current_confs.get(confID).getParticipants().add(call);
alision43a9b362013-05-01 16:30:15 -0400730 }
731 });
732
alision7f18fc82013-05-01 09:37:33 -0400733 }
734
735 @Override
alision43a9b362013-05-01 16:30:15 -0400736 public void addMainParticipant(final String confID) throws RemoteException {
737 getExecutor().execute(new SipRunnable() {
738 @Override
739 protected void doRun() throws SameThreadException, RemoteException {
740 Log.i(TAG, "SipService.addMainParticipant() thread running...");
741 callManagerJNI.addMainParticipant(confID);
742 }
743 });
744
alision7f18fc82013-05-01 09:37:33 -0400745 }
746
747 @Override
alision43a9b362013-05-01 16:30:15 -0400748 public void detachParticipant(final String callID) throws RemoteException {
749 getExecutor().execute(new SipRunnable() {
750 @Override
751 protected void doRun() throws SameThreadException, RemoteException {
752 Log.i(TAG, "SipService.detachParticipant() thread running...");
alision806e18e2013-06-21 15:30:17 -0400753 Log.i(TAG, "Detaching " + callID);
754 Iterator<Entry<String, Conference>> it = current_confs.entrySet().iterator();
755 Log.i(TAG, "current_confs size " + current_confs.size());
756 while (it.hasNext()) {
757 Conference tmp = it.next().getValue();
758 Log.i(TAG, "conf has " + tmp.getParticipants().size() + " participants");
759 if (tmp.contains(callID)) {
760 current_calls.put(callID, tmp.getCall(callID));
761 Log.i(TAG, "Call found and put in current_calls");
762 }
763 }
alision43a9b362013-05-01 16:30:15 -0400764 callManagerJNI.detachParticipant(callID);
765 }
766 });
767
alision7f18fc82013-05-01 09:37:33 -0400768 }
769
770 @Override
alision43a9b362013-05-01 16:30:15 -0400771 public void joinConference(final String sel_confID, final String drag_confID) throws RemoteException {
772 getExecutor().execute(new SipRunnable() {
773 @Override
774 protected void doRun() throws SameThreadException, RemoteException {
775 Log.i(TAG, "SipService.joinConference() thread running...");
776 callManagerJNI.joinConference(sel_confID, drag_confID);
777 }
778 });
779
alision7f18fc82013-05-01 09:37:33 -0400780 }
781
782 @Override
alision43a9b362013-05-01 16:30:15 -0400783 public void hangUpConference(final String confID) throws RemoteException {
784 getExecutor().execute(new SipRunnable() {
785 @Override
786 protected void doRun() throws SameThreadException, RemoteException {
787 Log.i(TAG, "SipService.joinConference() thread running...");
788 callManagerJNI.hangUpConference(confID);
789 }
790 });
791
alision7f18fc82013-05-01 09:37:33 -0400792 }
793
794 @Override
alision43a9b362013-05-01 16:30:15 -0400795 public void holdConference(final String confID) throws RemoteException {
796 getExecutor().execute(new SipRunnable() {
797 @Override
798 protected void doRun() throws SameThreadException, RemoteException {
799 Log.i(TAG, "SipService.holdConference() thread running...");
800 callManagerJNI.holdConference(confID);
801 }
802 });
803
alision7f18fc82013-05-01 09:37:33 -0400804 }
805
806 @Override
alision43a9b362013-05-01 16:30:15 -0400807 public void unholdConference(final String confID) throws RemoteException {
808 getExecutor().execute(new SipRunnable() {
809 @Override
810 protected void doRun() throws SameThreadException, RemoteException {
811 Log.i(TAG, "SipService.unholdConference() thread running...");
812 callManagerJNI.unholdConference(confID);
813 }
814 });
815
alision7f18fc82013-05-01 09:37:33 -0400816 }
Alexandre Lision67817192013-07-18 12:04:30 -0400817
alisioncd8fb912013-06-28 14:43:51 -0400818 @Override
819 public boolean isConferenceParticipant(final String callID) throws RemoteException {
820 class IsParticipant extends SipRunnableWithReturn {
821
822 @Override
823 protected Boolean doRun() throws SameThreadException {
824 Log.i(TAG, "SipService.isRecording() thread running...");
825 return callManagerJNI.isConferenceParticipant(callID);
826 }
827 }
828
829 IsParticipant runInstance = new IsParticipant();
830 getExecutor().execute(runInstance);
831 while (!runInstance.isDone()) {
832 }
833
834 return (Boolean) runInstance.getVal();
835 }
alision7f18fc82013-05-01 09:37:33 -0400836
837 @Override
alisiondf1dac92013-06-27 17:35:53 -0400838 public HashMap<String, Conference> getConferenceList() throws RemoteException {
Alexandre Lision67817192013-07-18 12:04:30 -0400839 // class ConfList extends SipRunnableWithReturn {
840 // @Override
841 // protected StringVect doRun() throws SameThreadException {
842 // Log.i(TAG, "SipService.getConferenceList() thread running...");
843 // return callManagerJNI.getConferenceList();
844 // }
845 // }
846 // ;
847 // ConfList runInstance = new ConfList();
848 // getExecutor().execute(runInstance);
849 // while (!runInstance.isDone()) {
850 // // Log.w(TAG, "Waiting for getConferenceList");
851 // }
852 // StringVect swigvect = (StringVect) runInstance.getVal();
853 //
854 // ArrayList<String> nativelist = new ArrayList<String>();
855 //
856 // for (int i = 0; i < swigvect.size(); i++)
857 // nativelist.add(swigvect.get(i));
858 //
859 // return nativelist;
alisiondf1dac92013-06-27 17:35:53 -0400860 return current_confs;
alision7f18fc82013-05-01 09:37:33 -0400861 }
862
863 @Override
alision907bde72013-06-20 14:40:37 -0400864 public List getParticipantList(final String confID) throws RemoteException {
865 class PartList extends SipRunnableWithReturn {
866 @Override
867 protected StringVect doRun() throws SameThreadException {
868 Log.i(TAG, "SipService.getAccountList() thread running...");
869 return callManagerJNI.getParticipantList(confID);
870 }
871 }
872 ;
873 PartList runInstance = new PartList();
874 getExecutor().execute(runInstance);
875 while (!runInstance.isDone()) {
876 // Log.w(TAG, "Waiting for getConferenceList");
877 }
878 StringVect swigvect = (StringVect) runInstance.getVal();
879
880 ArrayList<String> nativelist = new ArrayList<String>();
881
882 for (int i = 0; i < swigvect.size(); i++)
883 nativelist.add(swigvect.get(i));
884
885 return nativelist;
alision7f18fc82013-05-01 09:37:33 -0400886 }
alision806e18e2013-06-21 15:30:17 -0400887
alision1005ba12013-06-19 13:52:44 -0400888 @Override
alision7f18fc82013-05-01 09:37:33 -0400889 public String getConferenceId(String callID) throws RemoteException {
alision43a9b362013-05-01 16:30:15 -0400890 Log.e(TAG, "getConferenceList not implemented");
alision7f18fc82013-05-01 09:37:33 -0400891 return null;
892 }
893
894 @Override
alision806e18e2013-06-21 15:30:17 -0400895 public String getConferenceDetails(final String callID) throws RemoteException {
896 class ConfDetails extends SipRunnableWithReturn {
897 @Override
898 protected StringMap doRun() throws SameThreadException {
899 Log.i(TAG, "SipService.getAccountList() thread running...");
900 return callManagerJNI.getConferenceDetails(callID);
901 }
902 }
903 ;
904 ConfDetails runInstance = new ConfDetails();
905 getExecutor().execute(runInstance);
906 while (!runInstance.isDone()) {
907 // Log.w(TAG, "Waiting for getConferenceList");
908 }
909 StringMap swigvect = (StringMap) runInstance.getVal();
910
911 return swigvect.get("CONF_STATE");
alision7f18fc82013-05-01 09:37:33 -0400912 }
913
alision04a00182013-05-10 17:05:29 -0400914 @Override
915 public String getRecordPath() throws RemoteException {
916 class RecordPath extends SipRunnableWithReturn {
917
918 @Override
919 protected String doRun() throws SameThreadException {
920 Log.i(TAG, "SipService.getRecordPath() thread running...");
Adrien Béraud9360f242013-09-19 11:07:42 +1000921 return configurationManagerJNI.getRecordPath();
alision04a00182013-05-10 17:05:29 -0400922 }
923 }
924
925 RecordPath runInstance = new RecordPath();
926 getExecutor().execute(runInstance);
927 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400928 // Log.w(TAG, "Waiting for getRecordPath");
alision04a00182013-05-10 17:05:29 -0400929 }
930 String path = (String) runInstance.getVal();
931
932 return path;
933 }
934
935 @Override
Alexandre Lisiona764c682013-09-09 10:02:07 -0400936 public boolean toggleRecordingCall(final String id) throws RemoteException {
Adrien Béraud9360f242013-09-19 11:07:42 +1000937
Alexandre Lisiona764c682013-09-09 10:02:07 -0400938 class ToggleRecording extends SipRunnableWithReturn {
939
alision04a00182013-05-10 17:05:29 -0400940 @Override
Alexandre Lisiona764c682013-09-09 10:02:07 -0400941 protected Boolean doRun() throws SameThreadException {
942 Log.i(TAG, "SipService.toggleRecordingCall() thread running...");
943 return callManagerJNI.toggleRecording(id);
alision04a00182013-05-10 17:05:29 -0400944 }
Alexandre Lisiona764c682013-09-09 10:02:07 -0400945 }
946
947 ToggleRecording runInstance = new ToggleRecording();
948 getExecutor().execute(runInstance);
949 while (!runInstance.isDone()) {
950 }
951
952 return (Boolean) runInstance.getVal();
alision04a00182013-05-10 17:05:29 -0400953
954 }
Alexandre Lision67817192013-07-18 12:04:30 -0400955
alision50fa0722013-06-25 17:29:44 -0400956 @Override
alisiondf1dac92013-06-27 17:35:53 -0400957 public boolean isRecording(final String id) throws RemoteException {
958 class IsRecording extends SipRunnableWithReturn {
959
960 @Override
961 protected Boolean doRun() throws SameThreadException {
962 Log.i(TAG, "SipService.isRecording() thread running...");
963 return callManagerJNI.getIsRecording(id);
964 }
965 }
966
967 IsRecording runInstance = new IsRecording();
968 getExecutor().execute(runInstance);
969 while (!runInstance.isDone()) {
970 }
971
972 return (Boolean) runInstance.getVal();
Alexandre Lision67817192013-07-18 12:04:30 -0400973
alisiondf1dac92013-06-27 17:35:53 -0400974 }
Alexandre Lision67817192013-07-18 12:04:30 -0400975
alisiondf1dac92013-06-27 17:35:53 -0400976 @Override
alision50fa0722013-06-25 17:29:44 -0400977 public boolean startRecordedFilePlayback(final String filepath) throws RemoteException {
978 getExecutor().execute(new SipRunnable() {
979 @Override
980 protected void doRun() throws SameThreadException, RemoteException {
981 Log.i(TAG, "SipService.setRecordingCall() thread running...");
982 callManagerJNI.startRecordedFilePlayback(filepath);
983 }
984 });
985 return false;
986 }
987
988 @Override
989 public void stopRecordedFilePlayback(final String filepath) throws RemoteException {
990 getExecutor().execute(new SipRunnable() {
991 @Override
992 protected void doRun() throws SameThreadException, RemoteException {
993 Log.i(TAG, "SipService.stopRecordedFilePlayback() thread running...");
994 callManagerJNI.stopRecordedFilePlayback(filepath);
995 }
996 });
997 }
alision04a00182013-05-10 17:05:29 -0400998
999 @Override
1000 public void setRecordPath(final String path) throws RemoteException {
1001 getExecutor().execute(new SipRunnable() {
1002 @Override
1003 protected void doRun() throws SameThreadException, RemoteException {
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001004 Log.i(TAG, "SipService.setRecordPath() " + path + " thread running...");
Adrien Béraud9360f242013-09-19 11:07:42 +10001005 configurationManagerJNI.setRecordPath(path);
alision04a00182013-05-10 17:05:29 -04001006 }
1007 });
1008 }
1009
1010 @Override
1011 public void sendTextMessage(final String callID, final String message, final String from) throws RemoteException {
1012 getExecutor().execute(new SipRunnable() {
1013 @Override
1014 protected void doRun() throws SameThreadException, RemoteException {
1015 Log.i(TAG, "SipService.sendTextMessage() thread running...");
Alexandre Lision10314352013-07-17 15:06:56 -04001016 callManagerJNI.sendTextMessage(callID, message);
alision04a00182013-05-10 17:05:29 -04001017 }
1018 });
1019
1020 }
1021
alisiond295ec22013-05-17 10:12:13 -04001022 @Override
Alexandre Lision4cf78702013-10-16 13:43:23 -04001023 public List getAudioCodecList(final String accountID) throws RemoteException {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001024 class AudioCodecList extends SipRunnableWithReturn {
1025
1026 @Override
Alexandre Lision933ef0a2013-10-15 17:28:40 -04001027 protected ArrayList<Codec> doRun() throws SameThreadException {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001028 Log.i(TAG, "SipService.getAudioCodecList() thread running...");
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001029 ArrayList<Codec> results = new ArrayList<Codec>();
Alexandre Lision4cf78702013-10-16 13:43:23 -04001030
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001031 IntVect active_payloads = configurationManagerJNI.getActiveAudioCodecList(accountID);
1032 for (int i = 0; i < active_payloads.size(); ++i) {
1033
Alexandre Lision039a3cf2013-10-16 17:44:57 -04001034 results.add(new Codec(active_payloads.get(i), configurationManagerJNI.getAudioCodecDetails(active_payloads.get(i)), true));
Alexandre Lisione0045442013-10-25 09:16:19 -04001035
Alexandre Lision4cf78702013-10-16 13:43:23 -04001036 }
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001037
Alexandre Lision039a3cf2013-10-16 17:44:57 -04001038 // if (results.get(active_payloads.get(i)) != null) {
1039 // results.get(active_payloads.get(i)).setEnabled(true);
1040
1041 IntVect payloads = configurationManagerJNI.getAudioCodecList();
1042
1043 for (int i = 0; i < payloads.size(); ++i) {
1044 boolean isActive = false;
1045 for (Codec co : results) {
1046 if (co.getPayload().toString().contentEquals(String.valueOf(payloads.get(i))))
1047 isActive = true;
1048
1049 }
1050 if (isActive)
1051 continue;
1052 else
1053 results.add(new Codec(payloads.get(i), configurationManagerJNI.getAudioCodecDetails(payloads.get(i)), false));
1054
1055 }
1056
1057 // if (!results.containsKey(payloads.get(i))) {
1058 // results.put(payloads.get(i), new Codec(payloads.get(i), configurationManagerJNI.getAudioCodecDetails(payloads.get(i)), false));
1059 // Log.i(TAG, "Other, Adding:" + results.get((payloads.get(i))).getName());
1060 // }
1061
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001062 return results;
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001063 }
1064 }
1065
1066 AudioCodecList runInstance = new AudioCodecList();
1067 getExecutor().execute(runInstance);
1068 while (!runInstance.isDone()) {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001069 }
Alexandre Lision933ef0a2013-10-15 17:28:40 -04001070 ArrayList<Codec> codecs = (ArrayList<Codec>) runInstance.getVal();
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001071 return codecs;
alisiond295ec22013-05-17 10:12:13 -04001072 }
1073
alision9f7a6ec2013-05-24 16:26:26 -04001074 @Override
Alexandre Lision4cf78702013-10-16 13:43:23 -04001075 public Map getRingtoneList() throws RemoteException {
1076 class RingtoneList extends SipRunnableWithReturn {
1077
1078 @Override
1079 protected StringMap doRun() throws SameThreadException {
1080 Log.i(TAG, "SipService.getRingtoneList() thread running...");
1081 return configurationManagerJNI.getRingtoneList();
1082 }
1083 }
1084
1085 RingtoneList runInstance = new RingtoneList();
1086 getExecutor().execute(runInstance);
1087 while (!runInstance.isDone()) {
1088 }
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001089 StringMap ringtones = (StringMap) runInstance.getVal();
1090
1091 for (int i = 0; i < ringtones.size(); ++i) {
1092 // Log.i(TAG,"ringtones "+i+" "+ ringtones.);
1093 }
1094
Alexandre Lision4cf78702013-10-16 13:43:23 -04001095 return null;
1096 }
1097
1098 @Override
1099 public void setActiveCodecList(final List codecs, final String accountID) throws RemoteException {
1100 getExecutor().execute(new SipRunnable() {
1101 @Override
1102 protected void doRun() throws SameThreadException, RemoteException {
1103 Log.i(TAG, "SipService.setActiveAudioCodecList() thread running...");
1104 StringVect list = new StringVect();
1105 for (int i = 0; i < codecs.size(); ++i) {
1106 list.add((String) codecs.get(i));
1107 }
1108 configurationManagerJNI.setActiveAudioCodecList(list, accountID);
1109 }
1110 });
1111 }
1112
1113 @Override
alisionfde875f2013-05-28 17:01:54 -04001114 public HashMap<String, SipCall> getCallList() throws RemoteException {
alision85704182013-05-29 15:23:03 -04001115 // class CallList extends SipRunnableWithReturn {
1116 //
1117 // @Override
1118 // protected StringVect doRun() throws SameThreadException {
1119 // Log.i(TAG, "SipService.getCallList() thread running...");
1120 // return callManagerJNI.getCallList();
1121 // }
1122 // }
1123 //
1124 // CallList runInstance = new CallList();
1125 // getExecutor().execute(runInstance);
1126 // while (!runInstance.isDone()) {
1127 // Log.w(TAG, "Waiting for getAudioCodecList");
1128 // }
1129 // StringVect swigmap = (StringVect) runInstance.getVal();
1130 //
1131 // ArrayList<String> nativemap = new ArrayList<String>();
1132 // for (int i = 0; i < swigmap.size(); ++i) {
1133 //
1134 // String t = swigmap.get(i);
1135 // nativemap.add(t);
1136 // }
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001137 // if(callManagerJNI == null)
1138 // return new HashMap<String, SipCall>();
1139 //
1140 //
1141 // HashMap<String, SipCall> results = new HashMap<String, SipCall>();
1142 // StringVect calls = callManagerJNI.getCallList();
1143 // for(int i = 0 ; i < calls.size(); ++i){
1144 // results.put(calls.get(i), new SipCall(calls.get(i), callManagerJNI.getCallDetails(calls.get(i))));
1145 // }
alision9f7a6ec2013-05-24 16:26:26 -04001146
alision2cb99562013-05-30 17:02:20 -04001147 return getCurrent_calls();
alision9f7a6ec2013-05-24 16:26:26 -04001148 }
1149
alision85704182013-05-29 15:23:03 -04001150 @Override
1151 public SipCall getCall(String callID) throws RemoteException {
alision2cb99562013-05-30 17:02:20 -04001152 return getCurrent_calls().get(callID);
1153 }
1154
1155 /***********************
1156 * Notification API
1157 ***********************/
1158 @Override
1159 public void createNotification() throws RemoteException {
1160 makeNotification();
alisioncc7bb422013-06-06 15:31:39 -04001161
alision2cb99562013-05-30 17:02:20 -04001162 }
1163
1164 @Override
1165 public void destroyNotification() throws RemoteException {
1166 removeNotification();
alisioncc7bb422013-06-06 15:31:39 -04001167
alision2cb99562013-05-30 17:02:20 -04001168 }
alisioncc7bb422013-06-06 15:31:39 -04001169
Adrien Béraud9360f242013-09-19 11:07:42 +10001170 private final int NOTIFICATION_ID = new Random().nextInt(1000);
alisioncc7bb422013-06-06 15:31:39 -04001171
alision2cb99562013-05-30 17:02:20 -04001172 private void makeNotification() {
alisioncc7bb422013-06-06 15:31:39 -04001173 if (current_calls.size() == 0) {
alision2cb99562013-05-30 17:02:20 -04001174 return;
1175 }
1176 Intent notificationIntent = new Intent(getApplicationContext(), SFLPhoneHomeActivity.class);
alisioncc7bb422013-06-06 15:31:39 -04001177 PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 007, notificationIntent,
1178 PendingIntent.FLAG_UPDATE_CURRENT);
alision2cb99562013-05-30 17:02:20 -04001179
1180 NotificationManager nm = (NotificationManager) getBaseContext().getSystemService(Context.NOTIFICATION_SERVICE);
Adrien Béraud9360f242013-09-19 11:07:42 +10001181 nm.cancel(NOTIFICATION_ID); // clear previous notifications.
alision2cb99562013-05-30 17:02:20 -04001182
1183 NotificationCompat.Builder builder = new NotificationCompat.Builder(getBaseContext());
alisioncc7bb422013-06-06 15:31:39 -04001184 //
1185 // builder.setContent(view);
1186 builder.setContentIntent(contentIntent).setOngoing(true).setSmallIcon(R.drawable.ic_launcher)
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001187 .setContentTitle(getCurrent_calls().size() + " ongoing calls").setTicker("Pending calls").setWhen(System.currentTimeMillis())
1188 .setAutoCancel(false);
alision2cb99562013-05-30 17:02:20 -04001189 builder.setPriority(NotificationCompat.PRIORITY_MAX);
1190 Notification n = builder.build();
1191
1192 nm.notify(NOTIFICATION_ID, n);
alision2cb99562013-05-30 17:02:20 -04001193 }
1194
1195 public void removeNotification() {
1196 NotificationManager nm = (NotificationManager) getBaseContext().getSystemService(Context.NOTIFICATION_SERVICE);
1197 nm.cancel(NOTIFICATION_ID);
alision85704182013-05-29 15:23:03 -04001198 }
1199
alisiondf1dac92013-06-27 17:35:53 -04001200 @Override
1201 public Conference getCurrentCall() throws RemoteException {
Alexandre Lision67817192013-07-18 12:04:30 -04001202 for (SipCall i : current_calls.values()) {
Adrien Béraud9360f242013-09-19 11:07:42 +10001203
Alexandre Lisionc51ccb12013-09-11 16:00:30 -04001204 // Incoming >> Ongoing
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001205 if (i.isIncoming()) {
Alexandre Lisionc51ccb12013-09-11 16:00:30 -04001206 Conference tmp = new Conference("-1");
1207 tmp.getParticipants().add(i);
1208 return tmp;
1209 }
Adrien Béraud9360f242013-09-19 11:07:42 +10001210
Alexandre Lision67817192013-07-18 12:04:30 -04001211 if (i.isOngoing()) {
alisiondf1dac92013-06-27 17:35:53 -04001212 Conference tmp = new Conference("-1");
1213 tmp.getParticipants().add(i);
1214 return tmp;
1215 }
1216 }
Alexandre Lision67817192013-07-18 12:04:30 -04001217
1218 if (!current_confs.isEmpty()) {
alisiondf1dac92013-06-27 17:35:53 -04001219 return (Conference) current_confs.values().toArray()[0];
1220 }
1221 return null;
1222 }
1223
Alexandre Lision64dc8c02013-09-25 15:32:25 -04001224 @Override
1225 public void playDtmf(final String key) throws RemoteException {
1226 getExecutor().execute(new SipRunnable() {
1227 @Override
1228 protected void doRun() throws SameThreadException, RemoteException {
1229 Log.i(TAG, "SipService.playDtmf() thread running...");
1230 callManagerJNI.playDTMF(key);
1231 }
1232 });
1233 }
1234
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001235 @Override
1236 public List getConcurrentCalls() throws RemoteException {
1237 ArrayList<Conference> toReturn = new ArrayList<Conference>();
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001238
1239 for (SipCall sip : current_calls.values()) {
1240 if (!sip.isCurrent()) {
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001241 Conference tmp = new Conference("-1");
1242 tmp.getParticipants().add(sip);
1243 toReturn.add(tmp);
1244 }
1245 }
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001246
1247 Log.i(TAG, "toReturn SIZE " + toReturn.size());
1248
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001249 return toReturn;
1250 }
1251
Alexandre Lision4fb22622013-10-21 16:26:33 -04001252 @Override
1253 public String getCurrentAudioCodecName(String callID) throws RemoteException {
1254 return callManagerJNI.getCurrentAudioCodecName(callID);
1255 }
1256
Emeric Vigier6119d782012-09-21 18:04:14 -04001257 };
Alexandre Lision6d867b92013-10-25 15:36:28 -04001258
1259
1260 public void changeVolume(int currentVolume) {
1261// StringVect resultsInput = configurationManagerJNI.getAudioInputDeviceList();
1262// StringVect resultsOutput = configurationManagerJNI.getAudioOutputDeviceList();
1263//
1264// Log.i(TAG, "------------------> INPUT DEVICES");
1265// for(int i = 0 ; i < resultsInput.size(); ++i){
1266// Log.i(TAG, resultsInput.get(i));
1267// }
1268//
1269// Log.i(TAG, "------------------> OUTPUT DEVICES");
1270// for(int i = 0 ; i < resultsOutput.size(); ++i){
1271// Log.i(TAG, resultsOutput.get(i));
1272// }
1273
1274// Log.i(TAG,"AudioManager ------------> "+configurationManagerJNI.getAudioManager());
1275
1276 callManagerJNI.setVolume("speaker", currentVolume);
1277 }
Emeric Vigiereaf2c492012-09-19 14:38:20 -04001278}