blob: 123759aebde178266fc3491ceb9a2b2c5a31d0ca [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 Lision4ab53972013-11-04 16:59:18 -050037import org.sflphone.client.HomeActivity;
Alexandre Lision933ef0a2013-10-15 17:28:40 -040038import org.sflphone.model.Codec;
Alexandre Lision064e1e02013-10-01 16:18:42 -040039import org.sflphone.model.Conference;
40import org.sflphone.model.SipCall;
Alexandre Lisiond5686032013-10-29 11:09:21 -040041import org.sflphone.model.SipMessage;
Alexandre Lision064e1e02013-10-01 16:18:42 -040042import org.sflphone.receivers.IncomingReceiver;
Alexandre Lision6d867b92013-10-25 15:36:28 -040043import org.sflphone.utils.MediaManager;
Alexandre Lisione0045442013-10-25 09:16:19 -040044import org.sflphone.utils.SipNotifications;
Alexandre Lision2aae48d2013-12-04 13:50:38 -050045import org.sflphone.utils.SwigNativeConverter;
Alexandre Lision064e1e02013-10-01 16:18:42 -040046
alision2cb99562013-05-30 17:02:20 -040047import android.app.Notification;
48import android.app.NotificationManager;
49import android.app.PendingIntent;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040050import android.app.Service;
alision17052d42013-04-22 10:39:38 -040051import android.content.Context;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040052import android.content.Intent;
alision17052d42013-04-22 10:39:38 -040053import android.content.IntentFilter;
alision7f18fc82013-05-01 09:37:33 -040054import android.os.Bundle;
Emeric Vigier6119d782012-09-21 18:04:14 -040055import android.os.Handler;
56import android.os.HandlerThread;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040057import android.os.IBinder;
Emeric Vigier6119d782012-09-21 18:04:14 -040058import android.os.Looper;
59import android.os.Message;
alision5f899632013-04-22 17:26:56 -040060import android.os.RemoteException;
alision2cb99562013-05-30 17:02:20 -040061import android.support.v4.app.NotificationCompat;
alision17052d42013-04-22 10:39:38 -040062import android.support.v4.content.LocalBroadcastManager;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040063import android.util.Log;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040064
Emeric Vigiereaf2c492012-09-19 14:38:20 -040065public class SipService extends Service {
66
67 static final String TAG = "SipService";
68 static final int DELAY = 5000; /* 5 sec */
Emeric Vigier6119d782012-09-21 18:04:14 -040069 private SipServiceExecutor mExecutor;
70 private static HandlerThread executorThread;
alision3ea8f3c2013-07-16 17:35:35 -040071 private CallManager callManagerJNI;
Alexandre Lision67817192013-07-18 12:04:30 -040072 private ManagerImpl managerImpl;
Emeric Vigier0007dee2012-09-24 11:35:58 -040073 private CallManagerCallBack callManagerCallBack;
alision3ea8f3c2013-07-16 17:35:35 -040074 private ConfigurationManager configurationManagerJNI;
Alexandre Savardfccd1dc2012-10-17 17:31:38 -040075 private ConfigurationManagerCallback configurationManagerCallback;
Emeric Vigier6119d782012-09-21 18:04:14 -040076 private boolean isPjSipStackStarted = false;
alisioncc7bb422013-06-06 15:31:39 -040077
Alexandre Lisione0045442013-10-25 09:16:19 -040078 public SipNotifications notificationManager;
Alexandre Lision6d867b92013-10-25 15:36:28 -040079 public MediaManager mediaManager;
Alexandre Lisione0045442013-10-25 09:16:19 -040080
alision2cb99562013-05-30 17:02:20 -040081 private HashMap<String, SipCall> current_calls = new HashMap<String, SipCall>();
alision806e18e2013-06-21 15:30:17 -040082 private HashMap<String, Conference> current_confs = new HashMap<String, Conference>();
83 private IncomingReceiver receiver;
Emeric Vigier6119d782012-09-21 18:04:14 -040084
alision806e18e2013-06-21 15:30:17 -040085 public HashMap<String, Conference> getCurrent_confs() {
86 return current_confs;
87 }
alision43a9b362013-05-01 16:30:15 -040088
89 @Override
90 public boolean onUnbind(Intent i) {
91 super.onUnbind(i);
92 Log.i(TAG, "onUnbind(intent)");
Alexandre Lision0f550ee2013-10-25 15:34:38 -040093 return true;
94 }
Alexandre Lisiondd68f652013-10-28 11:00:12 -040095
Alexandre Lision0f550ee2013-10-25 15:34:38 -040096 @Override
Alexandre Lisiondd68f652013-10-28 11:00:12 -040097 public void onRebind(Intent i) {
Alexandre Lision0f550ee2013-10-25 15:34:38 -040098 super.onRebind(i);
alision43a9b362013-05-01 16:30:15 -040099 }
100
101 /* called once by startService() */
102 @Override
103 public void onCreate() {
104 Log.i(TAG, "onCreated");
105 super.onCreate();
106
alision43a9b362013-05-01 16:30:15 -0400107 IntentFilter callFilter = new IntentFilter(CallManagerCallBack.CALL_STATE_CHANGED);
108 callFilter.addAction(CallManagerCallBack.INCOMING_CALL);
109 callFilter.addAction(CallManagerCallBack.NEW_CALL_CREATED);
alision4a0eb092013-05-07 13:52:03 -0400110 callFilter.addAction(ConfigurationManagerCallback.ACCOUNT_STATE_CHANGED);
111 callFilter.addAction(ConfigurationManagerCallback.ACCOUNTS_CHANGED);
alision04a00182013-05-10 17:05:29 -0400112 callFilter.addAction(CallManagerCallBack.INCOMING_TEXT);
alision806e18e2013-06-21 15:30:17 -0400113 callFilter.addAction(CallManagerCallBack.CONF_CREATED);
114 callFilter.addAction(CallManagerCallBack.CONF_REMOVED);
115 callFilter.addAction(CallManagerCallBack.CONF_CHANGED);
alisiondf1dac92013-06-27 17:35:53 -0400116 callFilter.addAction(CallManagerCallBack.RECORD_STATE_CHANGED);
alision806e18e2013-06-21 15:30:17 -0400117 receiver = new IncomingReceiver(this, mBinder);
alision2cb99562013-05-30 17:02:20 -0400118 LocalBroadcastManager.getInstance(this).registerReceiver(receiver, callFilter);
alision2cb99562013-05-30 17:02:20 -0400119
alisioncc7bb422013-06-06 15:31:39 -0400120 getExecutor().execute(new StartRunnable());
Alexandre Lisione0045442013-10-25 09:16:19 -0400121
122 notificationManager = new SipNotifications(this);
Alexandre Lision6d867b92013-10-25 15:36:28 -0400123 mediaManager = new MediaManager(this);
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400124
Alexandre Lisione0045442013-10-25 09:16:19 -0400125 notificationManager.onServiceCreate();
Alexandre Lision6d867b92013-10-25 15:36:28 -0400126 mediaManager.startService();
Alexandre Lision3e2a1d02013-11-19 17:23:00 -0500127
128
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400129
alisioncc7bb422013-06-06 15:31:39 -0400130 }
alision43a9b362013-05-01 16:30:15 -0400131
132 /* called for each startService() */
133 @Override
134 public int onStartCommand(Intent intent, int flags, int startId) {
135 Log.i(TAG, "onStarted");
136 super.onStartCommand(intent, flags, startId);
137
alision806e18e2013-06-21 15:30:17 -0400138 receiver = new IncomingReceiver(this, mBinder);
Alexandre Lisione0045442013-10-25 09:16:19 -0400139
Alexandre Lision0f550ee2013-10-25 15:34:38 -0400140 return START_STICKY; /* started and stopped explicitly */
alision43a9b362013-05-01 16:30:15 -0400141 }
142
143 @Override
144 public void onDestroy() {
Alexandre Lision52214992013-10-28 17:41:23 -0400145 Log.i(TAG, "onDestroy");
alision43a9b362013-05-01 16:30:15 -0400146 /* called once by stopService() */
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400147
Alexandre Lision0a300ff2013-09-23 14:22:34 -0400148 LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
Alexandre Lisione0045442013-10-25 09:16:19 -0400149 notificationManager.onServiceDestroy();
Alexandre Lisionafbe8f62013-10-25 15:52:44 -0400150
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400151 getExecutor().execute(new FinalizeRunnable());
alision43a9b362013-05-01 16:30:15 -0400152 super.onDestroy();
153
alision43a9b362013-05-01 16:30:15 -0400154 }
155
156 @Override
157 public IBinder onBind(Intent arg0) {
158 Log.i(TAG, "onBound");
159 return mBinder;
160 }
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400161
alision43a9b362013-05-01 16:30:15 -0400162 private static Looper createLooper() {
163 if (executorThread == null) {
164 Log.d(TAG, "Creating new handler thread");
165 // ADT gives a fake warning due to bad parse rule.
166 executorThread = new HandlerThread("SipService.Executor");
167 executorThread.start();
168 }
169 return executorThread.getLooper();
170 }
171
172 public SipServiceExecutor getExecutor() {
173 // create mExecutor lazily
174 if (mExecutor == null) {
175 mExecutor = new SipServiceExecutor(this);
176 }
177 return mExecutor;
178 }
179
180 // Executes immediate tasks in a single executorThread.
181 public static class SipServiceExecutor extends Handler {
182 WeakReference<SipService> handlerService;
183
184 SipServiceExecutor(SipService s) {
185 super(createLooper());
186 handlerService = new WeakReference<SipService>(s);
187 }
188
189 public void execute(Runnable task) {
190 // TODO: add wakelock
191 Message.obtain(this, 0/* don't care */, task).sendToTarget();
Alexandre Lisioncdec5952013-07-17 14:18:22 -0400192 Log.w(TAG, "SenT!");
alision43a9b362013-05-01 16:30:15 -0400193 }
194
195 @Override
196 public void handleMessage(Message msg) {
197 if (msg.obj instanceof Runnable) {
198 executeInternal((Runnable) msg.obj);
199 } else {
200 Log.w(TAG, "can't handle msg: " + msg);
201 }
202 }
203
204 private void executeInternal(Runnable task) {
205 try {
206 task.run();
207 } catch (Throwable t) {
208 Log.e(TAG, "run task: " + task, t);
209 }
210 }
211 }
Alexandre Lision63870a72013-10-28 16:33:47 -0400212
213 private void stopDaemon() {
214 if (managerImpl != null) {
215 managerImpl.finish();
216 isPjSipStackStarted = false;
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400217 }
218 }
alision43a9b362013-05-01 16:30:15 -0400219
220 private void startPjSipStack() throws SameThreadException {
221 if (isPjSipStackStarted)
222 return;
223
224 try {
225 System.loadLibrary("gnustl_shared");
alision43a9b362013-05-01 16:30:15 -0400226 System.loadLibrary("crypto");
227 System.loadLibrary("ssl");
alision43a9b362013-05-01 16:30:15 -0400228 System.loadLibrary("sflphone");
229 isPjSipStackStarted = true;
Adrien Béraud9360f242013-09-19 11:07:42 +1000230
alision43a9b362013-05-01 16:30:15 -0400231 } catch (UnsatisfiedLinkError e) {
232 Log.e(TAG, "Problem with the current Pj stack...", e);
233 isPjSipStackStarted = false;
234 return;
235 } catch (Exception e) {
236 Log.e(TAG, "Problem with the current Pj stack...", e);
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400237 isPjSipStackStarted = false;
alision43a9b362013-05-01 16:30:15 -0400238 }
239
Alexandre Lision67817192013-07-18 12:04:30 -0400240 Log.i(TAG, "PjSIPStack started");
241 managerImpl = SFLPhoneservice.instance();
242
243 /* set static AppPath before calling manager.init */
Alexandre Lision63870a72013-10-28 16:33:47 -0400244 // managerImpl.setPath(getApplication().getFilesDir().getAbsolutePath());
alision43a9b362013-05-01 16:30:15 -0400245
alision3ea8f3c2013-07-16 17:35:35 -0400246 callManagerJNI = new CallManager();
alision43a9b362013-05-01 16:30:15 -0400247 callManagerCallBack = new CallManagerCallBack(this);
248 SFLPhoneservice.setCallbackObject(callManagerCallBack);
249
alision3ea8f3c2013-07-16 17:35:35 -0400250 configurationManagerJNI = new ConfigurationManager();
alision43a9b362013-05-01 16:30:15 -0400251 configurationManagerCallback = new ConfigurationManagerCallback(this);
252 SFLPhoneservice.setConfigurationCallbackObject(configurationManagerCallback);
Alexandre Lision67817192013-07-18 12:04:30 -0400253 managerImpl.init("");
Adrien Béraud9360f242013-09-19 11:07:42 +1000254
Alexandre Lision67817192013-07-18 12:04:30 -0400255 Log.i(TAG, "->startPjSipStack");
alision43a9b362013-05-01 16:30:15 -0400256 }
257
Adrien Béraud9360f242013-09-19 11:07:42 +1000258 public HashMap<String, SipCall> getCurrent_calls() {
alision2cb99562013-05-30 17:02:20 -0400259 return current_calls;
260 }
261
alision43a9b362013-05-01 16:30:15 -0400262 // Enforce same thread contract to ensure we do not call from somewhere else
263 public class SameThreadException extends Exception {
264 private static final long serialVersionUID = -905639124232613768L;
265
266 public SameThreadException() {
267 super("Should be launched from a single worker thread");
268 }
269 }
270
271 public abstract static class SipRunnable implements Runnable {
272 protected abstract void doRun() throws SameThreadException, RemoteException;
273
Adrien Béraud9360f242013-09-19 11:07:42 +1000274 @Override
alision43a9b362013-05-01 16:30:15 -0400275 public void run() {
276 try {
277 doRun();
278 } catch (SameThreadException e) {
279 Log.e(TAG, "Not done from same thread");
280 } catch (RemoteException e) {
281 Log.e(TAG, e.toString());
282 }
283 }
284 }
285
Alexandre Lisionfab23f82013-11-01 11:22:30 -0400286 public abstract class SipRunnableWithReturn implements Runnable {
alision43a9b362013-05-01 16:30:15 -0400287 Object obj = null;
288 boolean done = false;
289
290 protected abstract Object doRun() throws SameThreadException;
291
292 public Object getVal() {
293 return obj;
294 }
295
296 public boolean isDone() {
297 return done;
298 }
299
Adrien Béraud9360f242013-09-19 11:07:42 +1000300 @Override
alision43a9b362013-05-01 16:30:15 -0400301 public void run() {
302 try {
Alexandre Lisionfab23f82013-11-01 11:22:30 -0400303 if(isPjSipStackStarted)
304 obj = doRun();
alision43a9b362013-05-01 16:30:15 -0400305 done = true;
306 } catch (SameThreadException e) {
307 Log.e(TAG, "Not done from same thread");
308 }
309 }
310 }
311
312 class StartRunnable extends SipRunnable {
313 @Override
314 protected void doRun() throws SameThreadException {
315 startPjSipStack();
316 }
317 }
Alexandre Lision63870a72013-10-28 16:33:47 -0400318
Alexandre Lisiondd68f652013-10-28 11:00:12 -0400319 class FinalizeRunnable extends SipRunnable {
320 @Override
321 protected void doRun() throws SameThreadException {
322 stopDaemon();
323 }
324 }
alision43a9b362013-05-01 16:30:15 -0400325
alision43a9b362013-05-01 16:30:15 -0400326 /* ************************************
327 *
328 * Implement public interface for the service
329 *
Alexandre Lision67817192013-07-18 12:04:30 -0400330 * *********************************
331 */
332
Emeric Vigier6119d782012-09-21 18:04:14 -0400333 private final ISipService.Stub mBinder = new ISipService.Stub() {
334
335 @Override
alisionfde875f2013-05-28 17:01:54 -0400336 public void placeCall(final SipCall call) {
Emeric Vigier6119d782012-09-21 18:04:14 -0400337 getExecutor().execute(new SipRunnable() {
338 @Override
339 protected void doRun() throws SameThreadException {
340 Log.i(TAG, "SipService.placeCall() thread running...");
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400341 callManagerJNI.placeCall(call.getAccount().getAccountID(), call.getCallId(), call.getContact().getPhones().get(0).getNumber());
Adrien Béraud9360f242013-09-19 11:07:42 +1000342
Alexandre Lision2aae48d2013-12-04 13:50:38 -0500343 HashMap<String, String> details = SwigNativeConverter.convertCallDetailsToNative(callManagerJNI.getCallDetails(call.getCallId()));
Alexandre Lisionebeb3662013-09-17 16:20:54 -0400344 // watchout timestamp stored by sflphone is in seconds
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400345 call.setTimestamp_start(Long.parseLong(details.get(ServiceConstants.call.TIMESTAMP_START)));
alision2cb99562013-05-30 17:02:20 -0400346 getCurrent_calls().put(call.getCallId(), call);
Alexandre Lision6e9c7e52013-10-29 15:54:11 -0400347 mediaManager.obtainAudioFocus();
Emeric Vigier6119d782012-09-21 18:04:14 -0400348 }
349 });
350 }
351
352 @Override
353 public void refuse(final String callID) {
354 getExecutor().execute(new SipRunnable() {
355 @Override
356 protected void doRun() throws SameThreadException {
357 Log.i(TAG, "SipService.refuse() thread running...");
358 callManagerJNI.refuse(callID);
359 }
360 });
361 }
362
363 @Override
364 public void accept(final String callID) {
365 getExecutor().execute(new SipRunnable() {
366 @Override
367 protected void doRun() throws SameThreadException {
Tristan Matthews40cf25e2013-07-24 13:45:15 -0400368 Log.i(TAG, "SipService.accept() thread running...");
Emeric Vigier6119d782012-09-21 18:04:14 -0400369 callManagerJNI.accept(callID);
370 }
371 });
372 }
373
374 @Override
375 public void hangUp(final String callID) {
376 getExecutor().execute(new SipRunnable() {
377 @Override
378 protected void doRun() throws SameThreadException {
379 Log.i(TAG, "SipService.hangUp() thread running...");
380 callManagerJNI.hangUp(callID);
381 }
382 });
383 }
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400384
385 @Override
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400386 public void hold(final String callID) {
387 getExecutor().execute(new SipRunnable() {
388 @Override
389 protected void doRun() throws SameThreadException {
390 Log.i(TAG, "SipService.hold() thread running...");
391 callManagerJNI.hold(callID);
392 }
393 });
394 }
395
396 @Override
397 public void unhold(final String callID) {
398 getExecutor().execute(new SipRunnable() {
399 @Override
400 protected void doRun() throws SameThreadException {
401 Log.i(TAG, "SipService.unhold() thread running...");
402 callManagerJNI.unhold(callID);
403 }
404 });
405 }
Adrien Béraud9360f242013-09-19 11:07:42 +1000406
Alexandre Lision6711ab22013-09-16 15:15:38 -0400407 @Override
408 public HashMap<String, String> getCallDetails(String callID) throws RemoteException {
409 class CallDetails extends SipRunnableWithReturn {
410 private String id;
411
412 CallDetails(String callID) {
413 id = callID;
414 }
415
416 @Override
417 protected StringMap doRun() throws SameThreadException {
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400418 Log.i(TAG, "SipService.getCallDetails() thread running...");
Alexandre Lision6711ab22013-09-16 15:15:38 -0400419 return callManagerJNI.getCallDetails(id);
420 }
421 }
422
423 CallDetails runInstance = new CallDetails(callID);
424 getExecutor().execute(runInstance);
425
426 while (!runInstance.isDone()) {
427 }
428 StringMap swigmap = (StringMap) runInstance.getVal();
429
Alexandre Lision2aae48d2013-12-04 13:50:38 -0500430 HashMap<String, String> nativemap = SwigNativeConverter.convertCallDetailsToNative(swigmap);
Alexandre Lision6711ab22013-09-16 15:15:38 -0400431
432 return nativemap;
Adrien Béraud9360f242013-09-19 11:07:42 +1000433
Alexandre Lision6711ab22013-09-16 15:15:38 -0400434 }
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400435
436 @Override
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400437 public void setAudioPlugin(final String audioPlugin) {
438 getExecutor().execute(new SipRunnable() {
alision371b77e2013-04-23 14:51:26 -0400439 @Override
440 protected void doRun() throws SameThreadException {
441 Log.i(TAG, "SipService.setAudioPlugin() thread running...");
442 configurationManagerJNI.setAudioPlugin(audioPlugin);
443 }
Alexandre Savard31d27c62012-10-04 16:05:08 -0400444 });
445 }
446
447 @Override
448 public String getCurrentAudioOutputPlugin() {
449 class CurrentAudioPlugin extends SipRunnableWithReturn {
450 @Override
451 protected String doRun() throws SameThreadException {
452 Log.i(TAG, "SipService.getCurrentAudioOutputPlugin() thread running...");
453 return configurationManagerJNI.getCurrentAudioOutputPlugin();
454 }
alision371b77e2013-04-23 14:51:26 -0400455 }
456 ;
Alexandre Savard31d27c62012-10-04 16:05:08 -0400457
458 CurrentAudioPlugin runInstance = new CurrentAudioPlugin();
459 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400460 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400461 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400462 }
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400463 return (String) runInstance.getVal();
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400464 }
Alexandre Savard713a34d2012-09-26 15:50:41 -0400465
466 @Override
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400467 public ArrayList<String> getAccountList() {
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400468 class AccountList extends SipRunnableWithReturn {
469 @Override
470 protected StringVect doRun() throws SameThreadException {
471 Log.i(TAG, "SipService.getAccountList() thread running...");
472 return configurationManagerJNI.getAccountList();
473 }
alision371b77e2013-04-23 14:51:26 -0400474 }
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400475 AccountList runInstance = new AccountList();
Alexandre Lisioncdec5952013-07-17 14:18:22 -0400476 Log.i(TAG, "SipService.getAccountList() thread running...");
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400477 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400478 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400479 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400480 }
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400481 StringVect swigvect = (StringVect) runInstance.getVal();
482
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400483 ArrayList<String> nativelist = new ArrayList<String>();
Alexandre Savard52a72522012-09-27 16:40:13 -0400484
alision371b77e2013-04-23 14:51:26 -0400485 for (int i = 0; i < swigvect.size(); i++)
486 nativelist.add(swigvect.get(i));
Alexandre Savard52a72522012-09-27 16:40:13 -0400487
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400488 return nativelist;
alision371b77e2013-04-23 14:51:26 -0400489 }
Alexandre Lision4b4233a2013-10-16 17:24:17 -0400490
Alexandre Lision4cf78702013-10-16 13:43:23 -0400491 @Override
Alexandre Lision4b4233a2013-10-16 17:24:17 -0400492 public void setAccountOrder(final String order) {
Alexandre Lision4cf78702013-10-16 13:43:23 -0400493 getExecutor().execute(new SipRunnable() {
494 @Override
495 protected void doRun() throws SameThreadException {
496 Log.i(TAG, "SipService.setAccountsOrder() thread running...");
497 configurationManagerJNI.setAccountsOrder(order);
498 }
499 });
500 }
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400501
502 @Override
alision371b77e2013-04-23 14:51:26 -0400503 public HashMap<String, String> getAccountDetails(final String accountID) {
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400504 class AccountDetails extends SipRunnableWithReturn {
505 private String id;
alision371b77e2013-04-23 14:51:26 -0400506
507 AccountDetails(String accountId) {
508 id = accountId;
509 }
510
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400511 @Override
512 protected StringMap doRun() throws SameThreadException {
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400513 Log.i(TAG, "SipService.getAccountDetails() thread running...");
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400514 return configurationManagerJNI.getAccountDetails(id);
515 }
alision371b77e2013-04-23 14:51:26 -0400516 }
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400517
518 AccountDetails runInstance = new AccountDetails(accountID);
519 getExecutor().execute(runInstance);
alisionfde875f2013-05-28 17:01:54 -0400520
alision371b77e2013-04-23 14:51:26 -0400521 while (!runInstance.isDone()) {
522 }
523 StringMap swigmap = (StringMap) runInstance.getVal();
Alexandre Savard713a34d2012-09-26 15:50:41 -0400524
Alexandre Lision2aae48d2013-12-04 13:50:38 -0500525 HashMap<String, String> nativemap = SwigNativeConverter.convertAccountToNative(swigmap);
Alexandre Savard713a34d2012-09-26 15:50:41 -0400526
527 return nativemap;
528 }
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400529
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400530 @SuppressWarnings("unchecked")
531 // Hashmap runtime cast
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400532 @Override
alisioncc7bb422013-06-06 15:31:39 -0400533 public void setAccountDetails(final String accountId, final Map map) {
alision371b77e2013-04-23 14:51:26 -0400534 HashMap<String, String> nativemap = (HashMap<String, String>) map;
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400535
Alexandre Lision2aae48d2013-12-04 13:50:38 -0500536 final StringMap swigmap = SwigNativeConverter.convertFromNativeToSwig(nativemap);
Alexandre Savard718d49f2012-10-02 15:17:13 -0400537
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400538 getExecutor().execute(new SipRunnable() {
539 @Override
540 protected void doRun() throws SameThreadException {
alisioncc7bb422013-06-06 15:31:39 -0400541
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400542 configurationManagerJNI.setAccountDetails(accountId, swigmap);
alisioncc7bb422013-06-06 15:31:39 -0400543 Log.i(TAG, "SipService.setAccountDetails() thread running...");
544 }
545
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400546 });
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400547 }
548
Alexandre Lision451f2a82013-11-12 12:55:55 -0500549 @Override
550 public Map getAccountTemplate() throws RemoteException {
551 class AccountTemplate extends SipRunnableWithReturn {
552
553 @Override
554 protected StringMap doRun() throws SameThreadException {
555 Log.i(TAG, "SipService.getAccountTemplate() thread running...");
556 return configurationManagerJNI.getAccountTemplate();
557 }
558 }
559
560 AccountTemplate runInstance = new AccountTemplate();
561 getExecutor().execute(runInstance);
562
563 while (!runInstance.isDone()) {
564 }
565 StringMap swigmap = (StringMap) runInstance.getVal();
566
Alexandre Lision2aae48d2013-12-04 13:50:38 -0500567 HashMap<String, String> nativemap = SwigNativeConverter.convertAccountToNative(swigmap);
Alexandre Lision451f2a82013-11-12 12:55:55 -0500568
569 return nativemap;
570 }
alisioncc7bb422013-06-06 15:31:39 -0400571
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400572 @SuppressWarnings("unchecked")
573 // Hashmap runtime cast
Alexandre Savard46036572012-10-05 13:56:49 -0400574 @Override
575 public String addAccount(Map map) {
576 class AddAccount extends SipRunnableWithReturn {
577 StringMap map;
alision371b77e2013-04-23 14:51:26 -0400578
579 AddAccount(StringMap m) {
580 map = m;
581 }
582
Alexandre Savard46036572012-10-05 13:56:49 -0400583 @Override
584 protected String doRun() throws SameThreadException {
585 Log.i(TAG, "SipService.getAccountDetails() thread running...");
586 return configurationManagerJNI.addAccount(map);
587 }
alision371b77e2013-04-23 14:51:26 -0400588 }
Alexandre Savard46036572012-10-05 13:56:49 -0400589
Alexandre Lision2aae48d2013-12-04 13:50:38 -0500590 final StringMap swigmap = SwigNativeConverter.convertFromNativeToSwig((HashMap<String, String>) map);
Alexandre Savard46036572012-10-05 13:56:49 -0400591
592 AddAccount runInstance = new AddAccount(swigmap);
593 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400594 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400595 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400596 }
Alexandre Savard46036572012-10-05 13:56:49 -0400597 String accountId = (String) runInstance.getVal();
598
599 return accountId;
600 }
601
602 @Override
603 public void removeAccount(final String accountId) {
604 getExecutor().execute(new SipRunnable() {
605 @Override
606 protected void doRun() throws SameThreadException {
607 Log.i(TAG, "SipService.setAccountDetails() thread running...");
608 configurationManagerJNI.removeAccount(accountId);
609 }
610 });
611 }
alision5f899632013-04-22 17:26:56 -0400612
alisione2a38e12013-04-25 14:20:20 -0400613 @Override
614 public ArrayList<HashMap<String, String>> getHistory() throws RemoteException {
615 class History extends SipRunnableWithReturn {
616
617 @Override
618 protected VectMap doRun() throws SameThreadException {
619 Log.i(TAG, "SipService.getHistory() thread running...");
alision7f18fc82013-05-01 09:37:33 -0400620
alisione2a38e12013-04-25 14:20:20 -0400621 return configurationManagerJNI.getHistory();
622 }
623 }
624
625 History runInstance = new History();
626 getExecutor().execute(runInstance);
627 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400628 // Log.w(TAG, "Waiting for getHistory");
alisione2a38e12013-04-25 14:20:20 -0400629 }
alision1005ba12013-06-19 13:52:44 -0400630 Log.i(TAG, "SipService.getHistory() DONE");
alisione2a38e12013-04-25 14:20:20 -0400631 VectMap swigmap = (VectMap) runInstance.getVal();
632
Alexandre Lision2aae48d2013-12-04 13:50:38 -0500633 ArrayList<HashMap<String, String>> nativemap = SwigNativeConverter.convertHistoryToNative(swigmap);
alisione2a38e12013-04-25 14:20:20 -0400634
635 return nativemap;
636 }
alision7f18fc82013-05-01 09:37:33 -0400637
alision43a9b362013-05-01 16:30:15 -0400638 /*************************
639 * Transfer related API
640 *************************/
641
alision7f18fc82013-05-01 09:37:33 -0400642 @Override
643 public void transfer(final String callID, final String to) throws RemoteException {
644 getExecutor().execute(new SipRunnable() {
645 @Override
646 protected void doRun() throws SameThreadException, RemoteException {
647 Log.i(TAG, "SipService.transfer() thread running...");
648 if (callManagerJNI.transfer(callID, to)) {
649 Bundle bundle = new Bundle();
650 bundle.putString("CallID", callID);
651 bundle.putString("State", "HUNGUP");
652 Intent intent = new Intent(CallManagerCallBack.CALL_STATE_CHANGED);
alision7f18fc82013-05-01 09:37:33 -0400653 intent.putExtra("com.savoirfairelinux.sflphone.service.newstate", bundle);
alision84813a12013-05-27 17:40:39 -0400654 sendBroadcast(intent);
alision7f18fc82013-05-01 09:37:33 -0400655 } else
656 Log.i(TAG, "NOT OK");
657 }
658 });
659
660 }
alision43a9b362013-05-01 16:30:15 -0400661
alision7f18fc82013-05-01 09:37:33 -0400662 @Override
663 public void attendedTransfer(final String transferID, final String targetID) throws RemoteException {
664 getExecutor().execute(new SipRunnable() {
665 @Override
666 protected void doRun() throws SameThreadException, RemoteException {
alision43a9b362013-05-01 16:30:15 -0400667 Log.i(TAG, "SipService.attendedTransfer() thread running...");
alision7f18fc82013-05-01 09:37:33 -0400668 if (callManagerJNI.attendedTransfer(transferID, targetID)) {
669 Log.i(TAG, "OK");
alision7f18fc82013-05-01 09:37:33 -0400670 } else
671 Log.i(TAG, "NOT OK");
672 }
673 });
alision43a9b362013-05-01 16:30:15 -0400674
675 }
676
677 /*************************
678 * Conference related API
679 *************************/
680
681 @Override
682 public void removeConference(final String confID) throws RemoteException {
683 getExecutor().execute(new SipRunnable() {
684 @Override
685 protected void doRun() throws SameThreadException, RemoteException {
686 Log.i(TAG, "SipService.createConference() thread running...");
687 callManagerJNI.removeConference(confID);
688 }
689 });
690
alision7f18fc82013-05-01 09:37:33 -0400691 }
692
693 @Override
alision43a9b362013-05-01 16:30:15 -0400694 public void joinParticipant(final String sel_callID, final String drag_callID) throws RemoteException {
695 getExecutor().execute(new SipRunnable() {
696 @Override
697 protected void doRun() throws SameThreadException, RemoteException {
698 Log.i(TAG, "SipService.joinParticipant() thread running...");
699 callManagerJNI.joinParticipant(sel_callID, drag_callID);
alision806e18e2013-06-21 15:30:17 -0400700 // Generate a CONF_CREATED callback
alision43a9b362013-05-01 16:30:15 -0400701 }
702 });
703
alision7f18fc82013-05-01 09:37:33 -0400704 }
705
alision7f18fc82013-05-01 09:37:33 -0400706 @Override
alision806e18e2013-06-21 15:30:17 -0400707 public void addParticipant(final SipCall call, final String confID) throws RemoteException {
alision43a9b362013-05-01 16:30:15 -0400708 getExecutor().execute(new SipRunnable() {
709 @Override
710 protected void doRun() throws SameThreadException, RemoteException {
711 Log.i(TAG, "SipService.addParticipant() thread running...");
alision806e18e2013-06-21 15:30:17 -0400712 callManagerJNI.addParticipant(call.getCallId(), confID);
713 current_confs.get(confID).getParticipants().add(call);
alision43a9b362013-05-01 16:30:15 -0400714 }
715 });
716
alision7f18fc82013-05-01 09:37:33 -0400717 }
718
719 @Override
alision43a9b362013-05-01 16:30:15 -0400720 public void addMainParticipant(final String confID) throws RemoteException {
721 getExecutor().execute(new SipRunnable() {
722 @Override
723 protected void doRun() throws SameThreadException, RemoteException {
724 Log.i(TAG, "SipService.addMainParticipant() thread running...");
725 callManagerJNI.addMainParticipant(confID);
726 }
727 });
728
alision7f18fc82013-05-01 09:37:33 -0400729 }
730
731 @Override
alision43a9b362013-05-01 16:30:15 -0400732 public void detachParticipant(final String callID) throws RemoteException {
733 getExecutor().execute(new SipRunnable() {
734 @Override
735 protected void doRun() throws SameThreadException, RemoteException {
736 Log.i(TAG, "SipService.detachParticipant() thread running...");
alision806e18e2013-06-21 15:30:17 -0400737 Log.i(TAG, "Detaching " + callID);
738 Iterator<Entry<String, Conference>> it = current_confs.entrySet().iterator();
739 Log.i(TAG, "current_confs size " + current_confs.size());
740 while (it.hasNext()) {
741 Conference tmp = it.next().getValue();
742 Log.i(TAG, "conf has " + tmp.getParticipants().size() + " participants");
743 if (tmp.contains(callID)) {
744 current_calls.put(callID, tmp.getCall(callID));
745 Log.i(TAG, "Call found and put in current_calls");
746 }
747 }
alision43a9b362013-05-01 16:30:15 -0400748 callManagerJNI.detachParticipant(callID);
749 }
750 });
751
alision7f18fc82013-05-01 09:37:33 -0400752 }
753
754 @Override
alision43a9b362013-05-01 16:30:15 -0400755 public void joinConference(final String sel_confID, final String drag_confID) throws RemoteException {
756 getExecutor().execute(new SipRunnable() {
757 @Override
758 protected void doRun() throws SameThreadException, RemoteException {
759 Log.i(TAG, "SipService.joinConference() thread running...");
760 callManagerJNI.joinConference(sel_confID, drag_confID);
761 }
762 });
763
alision7f18fc82013-05-01 09:37:33 -0400764 }
765
766 @Override
alision43a9b362013-05-01 16:30:15 -0400767 public void hangUpConference(final String confID) throws RemoteException {
768 getExecutor().execute(new SipRunnable() {
769 @Override
770 protected void doRun() throws SameThreadException, RemoteException {
771 Log.i(TAG, "SipService.joinConference() thread running...");
772 callManagerJNI.hangUpConference(confID);
773 }
774 });
775
alision7f18fc82013-05-01 09:37:33 -0400776 }
777
778 @Override
alision43a9b362013-05-01 16:30:15 -0400779 public void holdConference(final String confID) throws RemoteException {
780 getExecutor().execute(new SipRunnable() {
781 @Override
782 protected void doRun() throws SameThreadException, RemoteException {
783 Log.i(TAG, "SipService.holdConference() thread running...");
784 callManagerJNI.holdConference(confID);
785 }
786 });
787
alision7f18fc82013-05-01 09:37:33 -0400788 }
789
790 @Override
alision43a9b362013-05-01 16:30:15 -0400791 public void unholdConference(final String confID) throws RemoteException {
792 getExecutor().execute(new SipRunnable() {
793 @Override
794 protected void doRun() throws SameThreadException, RemoteException {
795 Log.i(TAG, "SipService.unholdConference() thread running...");
796 callManagerJNI.unholdConference(confID);
797 }
798 });
799
alision7f18fc82013-05-01 09:37:33 -0400800 }
Alexandre Lision67817192013-07-18 12:04:30 -0400801
alisioncd8fb912013-06-28 14:43:51 -0400802 @Override
803 public boolean isConferenceParticipant(final String callID) throws RemoteException {
804 class IsParticipant extends SipRunnableWithReturn {
805
806 @Override
807 protected Boolean doRun() throws SameThreadException {
808 Log.i(TAG, "SipService.isRecording() thread running...");
809 return callManagerJNI.isConferenceParticipant(callID);
810 }
811 }
812
813 IsParticipant runInstance = new IsParticipant();
814 getExecutor().execute(runInstance);
815 while (!runInstance.isDone()) {
816 }
817
818 return (Boolean) runInstance.getVal();
819 }
alision7f18fc82013-05-01 09:37:33 -0400820
821 @Override
alisiondf1dac92013-06-27 17:35:53 -0400822 public HashMap<String, Conference> getConferenceList() throws RemoteException {
Alexandre Lision67817192013-07-18 12:04:30 -0400823 // class ConfList extends SipRunnableWithReturn {
824 // @Override
825 // protected StringVect doRun() throws SameThreadException {
826 // Log.i(TAG, "SipService.getConferenceList() thread running...");
827 // return callManagerJNI.getConferenceList();
828 // }
829 // }
830 // ;
831 // ConfList runInstance = new ConfList();
832 // getExecutor().execute(runInstance);
833 // while (!runInstance.isDone()) {
834 // // Log.w(TAG, "Waiting for getConferenceList");
835 // }
836 // StringVect swigvect = (StringVect) runInstance.getVal();
837 //
838 // ArrayList<String> nativelist = new ArrayList<String>();
839 //
840 // for (int i = 0; i < swigvect.size(); i++)
841 // nativelist.add(swigvect.get(i));
842 //
843 // return nativelist;
alisiondf1dac92013-06-27 17:35:53 -0400844 return current_confs;
alision7f18fc82013-05-01 09:37:33 -0400845 }
846
847 @Override
alision907bde72013-06-20 14:40:37 -0400848 public List getParticipantList(final String confID) throws RemoteException {
849 class PartList extends SipRunnableWithReturn {
850 @Override
851 protected StringVect doRun() throws SameThreadException {
852 Log.i(TAG, "SipService.getAccountList() thread running...");
853 return callManagerJNI.getParticipantList(confID);
854 }
855 }
856 ;
857 PartList runInstance = new PartList();
858 getExecutor().execute(runInstance);
859 while (!runInstance.isDone()) {
860 // Log.w(TAG, "Waiting for getConferenceList");
861 }
862 StringVect swigvect = (StringVect) runInstance.getVal();
863
864 ArrayList<String> nativelist = new ArrayList<String>();
865
866 for (int i = 0; i < swigvect.size(); i++)
867 nativelist.add(swigvect.get(i));
868
869 return nativelist;
alision7f18fc82013-05-01 09:37:33 -0400870 }
alision806e18e2013-06-21 15:30:17 -0400871
alision1005ba12013-06-19 13:52:44 -0400872 @Override
alision7f18fc82013-05-01 09:37:33 -0400873 public String getConferenceId(String callID) throws RemoteException {
alision43a9b362013-05-01 16:30:15 -0400874 Log.e(TAG, "getConferenceList not implemented");
alision7f18fc82013-05-01 09:37:33 -0400875 return null;
876 }
877
878 @Override
alision806e18e2013-06-21 15:30:17 -0400879 public String getConferenceDetails(final String callID) throws RemoteException {
880 class ConfDetails extends SipRunnableWithReturn {
881 @Override
882 protected StringMap doRun() throws SameThreadException {
883 Log.i(TAG, "SipService.getAccountList() thread running...");
884 return callManagerJNI.getConferenceDetails(callID);
885 }
886 }
887 ;
888 ConfDetails runInstance = new ConfDetails();
889 getExecutor().execute(runInstance);
890 while (!runInstance.isDone()) {
891 // Log.w(TAG, "Waiting for getConferenceList");
892 }
893 StringMap swigvect = (StringMap) runInstance.getVal();
894
895 return swigvect.get("CONF_STATE");
alision7f18fc82013-05-01 09:37:33 -0400896 }
897
alision04a00182013-05-10 17:05:29 -0400898 @Override
899 public String getRecordPath() throws RemoteException {
900 class RecordPath extends SipRunnableWithReturn {
901
902 @Override
903 protected String doRun() throws SameThreadException {
904 Log.i(TAG, "SipService.getRecordPath() thread running...");
Adrien Béraud9360f242013-09-19 11:07:42 +1000905 return configurationManagerJNI.getRecordPath();
alision04a00182013-05-10 17:05:29 -0400906 }
907 }
908
909 RecordPath runInstance = new RecordPath();
910 getExecutor().execute(runInstance);
911 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400912 // Log.w(TAG, "Waiting for getRecordPath");
alision04a00182013-05-10 17:05:29 -0400913 }
914 String path = (String) runInstance.getVal();
915
916 return path;
917 }
918
919 @Override
Alexandre Lisiona764c682013-09-09 10:02:07 -0400920 public boolean toggleRecordingCall(final String id) throws RemoteException {
Adrien Béraud9360f242013-09-19 11:07:42 +1000921
Alexandre Lisiona764c682013-09-09 10:02:07 -0400922 class ToggleRecording extends SipRunnableWithReturn {
923
alision04a00182013-05-10 17:05:29 -0400924 @Override
Alexandre Lisiona764c682013-09-09 10:02:07 -0400925 protected Boolean doRun() throws SameThreadException {
926 Log.i(TAG, "SipService.toggleRecordingCall() thread running...");
Alexandre Lision3874e552013-11-04 17:20:12 -0500927 boolean result = callManagerJNI.toggleRecording(id);
928
929 if(getCurrent_calls().containsKey(id)){
930 getCurrent_calls().get(id).setRecording(result);
931 } else if(getCurrent_confs().containsKey(id)){
932 getCurrent_confs().get(id).setRecording(result);
933 } else {
934 // A call in a conference has been put on hold
935 Iterator<Conference> it = getCurrent_confs().values().iterator();
936 while (it.hasNext()) {
937 Conference c = it.next();
938 if (c.getCall(id) != null)
939 c.getCall(id).setRecording(result);
940 }
941 }
942 return result;
alision04a00182013-05-10 17:05:29 -0400943 }
Alexandre Lisiona764c682013-09-09 10:02:07 -0400944 }
945
946 ToggleRecording runInstance = new ToggleRecording();
947 getExecutor().execute(runInstance);
948 while (!runInstance.isDone()) {
949 }
950
951 return (Boolean) runInstance.getVal();
alision04a00182013-05-10 17:05:29 -0400952
953 }
Alexandre Lision67817192013-07-18 12:04:30 -0400954
alision50fa0722013-06-25 17:29:44 -0400955 @Override
956 public boolean startRecordedFilePlayback(final String filepath) throws RemoteException {
957 getExecutor().execute(new SipRunnable() {
958 @Override
959 protected void doRun() throws SameThreadException, RemoteException {
960 Log.i(TAG, "SipService.setRecordingCall() thread running...");
961 callManagerJNI.startRecordedFilePlayback(filepath);
962 }
963 });
964 return false;
965 }
966
967 @Override
968 public void stopRecordedFilePlayback(final String filepath) throws RemoteException {
969 getExecutor().execute(new SipRunnable() {
970 @Override
971 protected void doRun() throws SameThreadException, RemoteException {
972 Log.i(TAG, "SipService.stopRecordedFilePlayback() thread running...");
973 callManagerJNI.stopRecordedFilePlayback(filepath);
974 }
975 });
976 }
alision04a00182013-05-10 17:05:29 -0400977
978 @Override
979 public void setRecordPath(final String path) throws RemoteException {
980 getExecutor().execute(new SipRunnable() {
981 @Override
982 protected void doRun() throws SameThreadException, RemoteException {
Alexandre Lisionb4a9e392013-10-01 14:39:43 -0400983 Log.i(TAG, "SipService.setRecordPath() " + path + " thread running...");
Adrien Béraud9360f242013-09-19 11:07:42 +1000984 configurationManagerJNI.setRecordPath(path);
alision04a00182013-05-10 17:05:29 -0400985 }
986 });
987 }
988
989 @Override
Alexandre Lisiond5686032013-10-29 11:09:21 -0400990 public void sendTextMessage(final String callID, final SipMessage message) throws RemoteException {
alision04a00182013-05-10 17:05:29 -0400991 getExecutor().execute(new SipRunnable() {
992 @Override
993 protected void doRun() throws SameThreadException, RemoteException {
994 Log.i(TAG, "SipService.sendTextMessage() thread running...");
Alexandre Lisiond5686032013-10-29 11:09:21 -0400995 callManagerJNI.sendTextMessage(callID, message.comment);
Alexandre Lisiond5545232013-10-29 11:24:02 -0400996 if(getCurrent_calls().get(callID) != null)
997 getCurrent_calls().get(callID).addSipMessage(message);
998 else if(getCurrent_confs().get(callID) != null)
999 getCurrent_confs().get(callID).addSipMessage(message);
alision04a00182013-05-10 17:05:29 -04001000 }
1001 });
1002
1003 }
1004
alisiond295ec22013-05-17 10:12:13 -04001005 @Override
Alexandre Lision4cf78702013-10-16 13:43:23 -04001006 public List getAudioCodecList(final String accountID) throws RemoteException {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001007 class AudioCodecList extends SipRunnableWithReturn {
1008
1009 @Override
Alexandre Lision933ef0a2013-10-15 17:28:40 -04001010 protected ArrayList<Codec> doRun() throws SameThreadException {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001011 Log.i(TAG, "SipService.getAudioCodecList() thread running...");
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001012 ArrayList<Codec> results = new ArrayList<Codec>();
Alexandre Lision4cf78702013-10-16 13:43:23 -04001013
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001014 IntVect active_payloads = configurationManagerJNI.getActiveAudioCodecList(accountID);
1015 for (int i = 0; i < active_payloads.size(); ++i) {
1016
Alexandre Lision039a3cf2013-10-16 17:44:57 -04001017 results.add(new Codec(active_payloads.get(i), configurationManagerJNI.getAudioCodecDetails(active_payloads.get(i)), true));
Alexandre Lisione0045442013-10-25 09:16:19 -04001018
Alexandre Lision4cf78702013-10-16 13:43:23 -04001019 }
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001020
Alexandre Lision039a3cf2013-10-16 17:44:57 -04001021 // if (results.get(active_payloads.get(i)) != null) {
1022 // results.get(active_payloads.get(i)).setEnabled(true);
Alexandre Lision451f2a82013-11-12 12:55:55 -05001023
Alexandre Lision039a3cf2013-10-16 17:44:57 -04001024 IntVect payloads = configurationManagerJNI.getAudioCodecList();
1025
1026 for (int i = 0; i < payloads.size(); ++i) {
1027 boolean isActive = false;
1028 for (Codec co : results) {
1029 if (co.getPayload().toString().contentEquals(String.valueOf(payloads.get(i))))
1030 isActive = true;
1031
1032 }
1033 if (isActive)
1034 continue;
1035 else
1036 results.add(new Codec(payloads.get(i), configurationManagerJNI.getAudioCodecDetails(payloads.get(i)), false));
1037
1038 }
1039
1040 // if (!results.containsKey(payloads.get(i))) {
1041 // results.put(payloads.get(i), new Codec(payloads.get(i), configurationManagerJNI.getAudioCodecDetails(payloads.get(i)), false));
1042 // Log.i(TAG, "Other, Adding:" + results.get((payloads.get(i))).getName());
1043 // }
1044
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001045 return results;
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001046 }
1047 }
1048
1049 AudioCodecList runInstance = new AudioCodecList();
1050 getExecutor().execute(runInstance);
1051 while (!runInstance.isDone()) {
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001052 }
Alexandre Lision933ef0a2013-10-15 17:28:40 -04001053 ArrayList<Codec> codecs = (ArrayList<Codec>) runInstance.getVal();
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001054 return codecs;
alisiond295ec22013-05-17 10:12:13 -04001055 }
1056
alision9f7a6ec2013-05-24 16:26:26 -04001057 @Override
Alexandre Lision4cf78702013-10-16 13:43:23 -04001058 public Map getRingtoneList() throws RemoteException {
1059 class RingtoneList extends SipRunnableWithReturn {
1060
1061 @Override
1062 protected StringMap doRun() throws SameThreadException {
1063 Log.i(TAG, "SipService.getRingtoneList() thread running...");
1064 return configurationManagerJNI.getRingtoneList();
1065 }
1066 }
1067
1068 RingtoneList runInstance = new RingtoneList();
1069 getExecutor().execute(runInstance);
1070 while (!runInstance.isDone()) {
1071 }
Alexandre Lision4b4233a2013-10-16 17:24:17 -04001072 StringMap ringtones = (StringMap) runInstance.getVal();
1073
1074 for (int i = 0; i < ringtones.size(); ++i) {
1075 // Log.i(TAG,"ringtones "+i+" "+ ringtones.);
1076 }
1077
Alexandre Lision4cf78702013-10-16 13:43:23 -04001078 return null;
1079 }
1080
1081 @Override
1082 public void setActiveCodecList(final List codecs, final String accountID) throws RemoteException {
1083 getExecutor().execute(new SipRunnable() {
1084 @Override
1085 protected void doRun() throws SameThreadException, RemoteException {
1086 Log.i(TAG, "SipService.setActiveAudioCodecList() thread running...");
1087 StringVect list = new StringVect();
1088 for (int i = 0; i < codecs.size(); ++i) {
1089 list.add((String) codecs.get(i));
1090 }
1091 configurationManagerJNI.setActiveAudioCodecList(list, accountID);
1092 }
1093 });
1094 }
1095
1096 @Override
alisionfde875f2013-05-28 17:01:54 -04001097 public HashMap<String, SipCall> getCallList() throws RemoteException {
alision85704182013-05-29 15:23:03 -04001098 // class CallList extends SipRunnableWithReturn {
1099 //
1100 // @Override
1101 // protected StringVect doRun() throws SameThreadException {
1102 // Log.i(TAG, "SipService.getCallList() thread running...");
1103 // return callManagerJNI.getCallList();
1104 // }
1105 // }
1106 //
1107 // CallList runInstance = new CallList();
1108 // getExecutor().execute(runInstance);
1109 // while (!runInstance.isDone()) {
1110 // Log.w(TAG, "Waiting for getAudioCodecList");
1111 // }
1112 // StringVect swigmap = (StringVect) runInstance.getVal();
1113 //
1114 // ArrayList<String> nativemap = new ArrayList<String>();
1115 // for (int i = 0; i < swigmap.size(); ++i) {
1116 //
1117 // String t = swigmap.get(i);
1118 // nativemap.add(t);
1119 // }
Alexandre Lisionafd40e42013-10-15 13:48:37 -04001120 // if(callManagerJNI == null)
1121 // return new HashMap<String, SipCall>();
1122 //
1123 //
1124 // HashMap<String, SipCall> results = new HashMap<String, SipCall>();
1125 // StringVect calls = callManagerJNI.getCallList();
1126 // for(int i = 0 ; i < calls.size(); ++i){
1127 // results.put(calls.get(i), new SipCall(calls.get(i), callManagerJNI.getCallDetails(calls.get(i))));
1128 // }
alision9f7a6ec2013-05-24 16:26:26 -04001129
alision2cb99562013-05-30 17:02:20 -04001130 return getCurrent_calls();
alision9f7a6ec2013-05-24 16:26:26 -04001131 }
1132
alision85704182013-05-29 15:23:03 -04001133 @Override
1134 public SipCall getCall(String callID) throws RemoteException {
alision2cb99562013-05-30 17:02:20 -04001135 return getCurrent_calls().get(callID);
1136 }
1137
1138 /***********************
1139 * Notification API
1140 ***********************/
1141 @Override
1142 public void createNotification() throws RemoteException {
1143 makeNotification();
alisioncc7bb422013-06-06 15:31:39 -04001144
alision2cb99562013-05-30 17:02:20 -04001145 }
1146
1147 @Override
1148 public void destroyNotification() throws RemoteException {
1149 removeNotification();
alisioncc7bb422013-06-06 15:31:39 -04001150
alision2cb99562013-05-30 17:02:20 -04001151 }
alisioncc7bb422013-06-06 15:31:39 -04001152
Adrien Béraud9360f242013-09-19 11:07:42 +10001153 private final int NOTIFICATION_ID = new Random().nextInt(1000);
alisioncc7bb422013-06-06 15:31:39 -04001154
alision2cb99562013-05-30 17:02:20 -04001155 private void makeNotification() {
alisioncc7bb422013-06-06 15:31:39 -04001156 if (current_calls.size() == 0) {
alision2cb99562013-05-30 17:02:20 -04001157 return;
1158 }
Alexandre Lision4ab53972013-11-04 16:59:18 -05001159 Intent notificationIntent = new Intent(getApplicationContext(), HomeActivity.class);
alisioncc7bb422013-06-06 15:31:39 -04001160 PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 007, notificationIntent,
1161 PendingIntent.FLAG_UPDATE_CURRENT);
alision2cb99562013-05-30 17:02:20 -04001162
1163 NotificationManager nm = (NotificationManager) getBaseContext().getSystemService(Context.NOTIFICATION_SERVICE);
Adrien Béraud9360f242013-09-19 11:07:42 +10001164 nm.cancel(NOTIFICATION_ID); // clear previous notifications.
alision2cb99562013-05-30 17:02:20 -04001165
1166 NotificationCompat.Builder builder = new NotificationCompat.Builder(getBaseContext());
Alexandre Lision5f733bc2013-12-04 13:10:30 -05001167
alisioncc7bb422013-06-06 15:31:39 -04001168 builder.setContentIntent(contentIntent).setOngoing(true).setSmallIcon(R.drawable.ic_launcher)
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001169 .setContentTitle(getCurrent_calls().size() + " ongoing calls").setTicker("Pending calls").setWhen(System.currentTimeMillis())
1170 .setAutoCancel(false);
alision2cb99562013-05-30 17:02:20 -04001171 builder.setPriority(NotificationCompat.PRIORITY_MAX);
1172 Notification n = builder.build();
1173
1174 nm.notify(NOTIFICATION_ID, n);
alision2cb99562013-05-30 17:02:20 -04001175 }
1176
1177 public void removeNotification() {
1178 NotificationManager nm = (NotificationManager) getBaseContext().getSystemService(Context.NOTIFICATION_SERVICE);
1179 nm.cancel(NOTIFICATION_ID);
alision85704182013-05-29 15:23:03 -04001180 }
1181
alisiondf1dac92013-06-27 17:35:53 -04001182 @Override
1183 public Conference getCurrentCall() throws RemoteException {
Alexandre Lision67817192013-07-18 12:04:30 -04001184 for (SipCall i : current_calls.values()) {
Adrien Béraud9360f242013-09-19 11:07:42 +10001185
Alexandre Lisionc51ccb12013-09-11 16:00:30 -04001186 // Incoming >> Ongoing
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001187 if (i.isIncoming()) {
Alexandre Lisionc51ccb12013-09-11 16:00:30 -04001188 Conference tmp = new Conference("-1");
1189 tmp.getParticipants().add(i);
1190 return tmp;
1191 }
Adrien Béraud9360f242013-09-19 11:07:42 +10001192
Alexandre Lision67817192013-07-18 12:04:30 -04001193 if (i.isOngoing()) {
alisiondf1dac92013-06-27 17:35:53 -04001194 Conference tmp = new Conference("-1");
1195 tmp.getParticipants().add(i);
1196 return tmp;
1197 }
1198 }
Alexandre Lision67817192013-07-18 12:04:30 -04001199
1200 if (!current_confs.isEmpty()) {
alisiondf1dac92013-06-27 17:35:53 -04001201 return (Conference) current_confs.values().toArray()[0];
1202 }
1203 return null;
1204 }
1205
Alexandre Lision64dc8c02013-09-25 15:32:25 -04001206 @Override
1207 public void playDtmf(final String key) throws RemoteException {
1208 getExecutor().execute(new SipRunnable() {
1209 @Override
1210 protected void doRun() throws SameThreadException, RemoteException {
1211 Log.i(TAG, "SipService.playDtmf() thread running...");
1212 callManagerJNI.playDTMF(key);
1213 }
1214 });
1215 }
1216
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001217 @Override
1218 public List getConcurrentCalls() throws RemoteException {
1219 ArrayList<Conference> toReturn = new ArrayList<Conference>();
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001220
1221 for (SipCall sip : current_calls.values()) {
1222 if (!sip.isCurrent()) {
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001223 Conference tmp = new Conference("-1");
1224 tmp.getParticipants().add(sip);
1225 toReturn.add(tmp);
1226 }
1227 }
Alexandre Lisionb4a9e392013-10-01 14:39:43 -04001228
1229 Log.i(TAG, "toReturn SIZE " + toReturn.size());
1230
Alexandre Lision6ae652d2013-09-26 16:39:20 -04001231 return toReturn;
1232 }
1233
Alexandre Lision4fb22622013-10-21 16:26:33 -04001234 @Override
1235 public String getCurrentAudioCodecName(String callID) throws RemoteException {
1236 return callManagerJNI.getCurrentAudioCodecName(callID);
1237 }
1238
Alexandre Lision31e30902013-11-08 15:16:59 -05001239 @Override
1240 public void setMuted(final boolean mute) throws RemoteException {
1241 getExecutor().execute(new SipRunnable() {
1242 @Override
1243 protected void doRun() throws SameThreadException, RemoteException {
1244 Log.i(TAG, "SipService.setMuted() thread running...");
1245 configurationManagerJNI.muteCapture(mute);
1246 }
1247 });
1248 }
1249
1250 @Override
1251 public boolean isCaptureMuted() throws RemoteException {
1252 class IsMuted extends SipRunnableWithReturn {
1253
1254 @Override
1255 protected Boolean doRun() throws SameThreadException {
1256 Log.i(TAG, "SipService.isCaptureMuted() thread running...");
1257 return configurationManagerJNI.isCaptureMuted();
1258 }
1259 }
1260
1261 IsMuted runInstance = new IsMuted();
1262 getExecutor().execute(runInstance);
1263 while (!runInstance.isDone()) {
1264 }
1265
1266 return (Boolean) runInstance.getVal();
1267 }
1268
Alexandre Lision3b7148e2013-11-13 17:23:06 -05001269 @Override
1270 public List getCredentials(final String accountID) throws RemoteException {
1271 class Credentials extends SipRunnableWithReturn {
1272
1273 @Override
1274 protected List doRun() throws SameThreadException {
1275 Log.i(TAG, "SipService.getCredentials() thread running...");
1276 VectMap map = configurationManagerJNI.getCredentials(accountID);
Alexandre Lision2aae48d2013-12-04 13:50:38 -05001277 ArrayList<HashMap<String, String>> result = SwigNativeConverter.convertCredentialsToNative(map);
Alexandre Lision3b7148e2013-11-13 17:23:06 -05001278 return result;
1279 }
1280 }
1281
1282 Credentials runInstance = new Credentials();
1283 getExecutor().execute(runInstance);
1284 while (!runInstance.isDone()) {
1285 }
1286 return (List) runInstance.getVal();
1287 }
1288
1289 @Override
1290 public void setCredentials(final String accountID, final List creds) throws RemoteException {
1291 getExecutor().execute(new SipRunnable() {
1292 @Override
1293 protected void doRun() throws SameThreadException, RemoteException {
1294 Log.i(TAG, "SipService.setCredentials() thread running...");
Alexandre Lision3cefec22013-11-14 17:26:35 -05001295 ArrayList<HashMap<String, String>> list = (ArrayList<HashMap<String, String>>) creds;
Alexandre Lision2aae48d2013-12-04 13:50:38 -05001296 configurationManagerJNI.setCredentials(accountID, SwigNativeConverter.convertFromNativeToSwig(creds));
Alexandre Lision3b7148e2013-11-13 17:23:06 -05001297 }
1298 });
1299 }
1300
Alexandre Lision3e2a1d02013-11-19 17:23:00 -05001301 @Override
1302 public void registerAllAccounts() throws RemoteException {
1303 getExecutor().execute(new SipRunnable() {
1304 @Override
1305 protected void doRun() throws SameThreadException, RemoteException {
1306 Log.i(TAG, "SipService.registerAllAccounts() thread running...");
1307 configurationManagerJNI.registerAllAccounts();
1308 }
1309 });
1310 }
1311
Alexandre Lision5f733bc2013-12-04 13:10:30 -05001312 /**
1313 * Not working yet
1314 */
1315 @Override
1316 public List getAudioInputDeviceList() throws RemoteException {
1317 class AudioInputDevices extends SipRunnableWithReturn {
1318
1319 @Override
1320 protected List doRun() throws SameThreadException {
1321 Log.i(TAG, "SipService.getCredentials() thread running...");
1322 StringVect map = configurationManagerJNI.getAudioInputDeviceList();
1323 ArrayList<HashMap<String, String>> result = new ArrayList<HashMap<String,String>>();
1324 return result;
1325 }
1326 }
1327
1328 AudioInputDevices runInstance = new AudioInputDevices();
1329 getExecutor().execute(runInstance);
1330 while (!runInstance.isDone()) {
1331 }
1332 return (List) runInstance.getVal();
1333 }
1334
1335 /**
1336 * Not working yet
1337 */
1338 @Override
1339 public List getAudioOutputDeviceList() throws RemoteException {
1340 class AudioOutputDevices extends SipRunnableWithReturn {
1341
1342 @Override
1343 protected List doRun() throws SameThreadException {
1344 Log.i(TAG, "SipService.getCredentials() thread running...");
1345 StringVect map = configurationManagerJNI.getAudioOutputDeviceList();
1346 ArrayList<HashMap<String, String>> result = new ArrayList<HashMap<String,String>>();
1347 return result;
1348 }
1349 }
1350
1351 AudioOutputDevices runInstance = new AudioOutputDevices();
1352 getExecutor().execute(runInstance);
1353 while (!runInstance.isDone()) {
1354 }
1355 return (List) runInstance.getVal();
1356 }
1357
Alexandre Lision451f2a82013-11-12 12:55:55 -05001358
1359
Emeric Vigier6119d782012-09-21 18:04:14 -04001360 };
Alexandre Lision63870a72013-10-28 16:33:47 -04001361}