blob: 1abfdaa730a6a1e82fee1bac6fe587c26d9532f7 [file] [log] [blame]
Emeric Vigier6119d782012-09-21 18:04:14 -04001/**
2 * Copyright (C) 2010-2012 Regis Montoya (aka r3gis - www.r3gis.fr)
3 * Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
4 *
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 */
Emeric Vigiereaf2c492012-09-19 14:38:20 -040025package com.savoirfairelinux.sflphone.service;
26
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;
alision7f18fc82013-05-01 09:37:33 -040030import java.util.List;
alision17052d42013-04-22 10:39:38 -040031import java.util.Map;
Emeric Vigier6119d782012-09-21 18:04:14 -040032
Emeric Vigiereaf2c492012-09-19 14:38:20 -040033import android.app.Service;
alision17052d42013-04-22 10:39:38 -040034import android.content.BroadcastReceiver;
35import android.content.Context;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040036import android.content.Intent;
alision17052d42013-04-22 10:39:38 -040037import android.content.IntentFilter;
alision7f18fc82013-05-01 09:37:33 -040038import android.os.Bundle;
Emeric Vigier6119d782012-09-21 18:04:14 -040039import android.os.Handler;
40import android.os.HandlerThread;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040041import android.os.IBinder;
Emeric Vigier6119d782012-09-21 18:04:14 -040042import android.os.Looper;
43import android.os.Message;
alisionfde875f2013-05-28 17:01:54 -040044import android.os.Parcelable;
alision5f899632013-04-22 17:26:56 -040045import android.os.RemoteException;
alision43a9b362013-05-01 16:30:15 -040046import android.os.Vibrator;
alision17052d42013-04-22 10:39:38 -040047import android.support.v4.content.LocalBroadcastManager;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040048import android.util.Log;
49import android.widget.Toast;
50
alisionf76de3b2013-04-16 15:35:22 -040051import com.savoirfairelinux.sflphone.account.AccountDetailsHandler;
alisiond295ec22013-05-17 10:12:13 -040052import com.savoirfairelinux.sflphone.account.AudioHandler;
alisione2a38e12013-04-25 14:20:20 -040053import com.savoirfairelinux.sflphone.account.HistoryHandler;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040054import com.savoirfairelinux.sflphone.client.SFLphoneApplication;
alisionfde875f2013-05-28 17:01:54 -040055import com.savoirfairelinux.sflphone.model.CallContact;
56import com.savoirfairelinux.sflphone.model.SipCall;
Alexandre Savard713a34d2012-09-26 15:50:41 -040057
Emeric Vigiereaf2c492012-09-19 14:38:20 -040058public class SipService extends Service {
59
60 static final String TAG = "SipService";
61 static final int DELAY = 5000; /* 5 sec */
62 private boolean runFlag = false;
63 private SipServiceThread sipServiceThread;
Emeric Vigier84e05da2012-09-20 14:53:05 -040064 private SFLphoneApplication sflphoneApp;
Emeric Vigier6119d782012-09-21 18:04:14 -040065 private SipServiceExecutor mExecutor;
66 private static HandlerThread executorThread;
67 private CallManagerJNI callManagerJNI;
Emeric Vigier0007dee2012-09-24 11:35:58 -040068 private CallManagerCallBack callManagerCallBack;
Alexandre Savardc1b08fe2012-09-25 16:24:47 -040069 private ConfigurationManagerJNI configurationManagerJNI;
Alexandre Savardfccd1dc2012-10-17 17:31:38 -040070 private ConfigurationManagerCallback configurationManagerCallback;
Emeric Vigier0007dee2012-09-24 11:35:58 -040071 private ManagerImpl managerImpl;
Emeric Vigier6119d782012-09-21 18:04:14 -040072 private boolean isPjSipStackStarted = false;
alision04a00182013-05-10 17:05:29 -040073
alision85704182013-05-29 15:23:03 -040074 HashMap<String, SipCall> current_calls = new HashMap<String, SipCall>();
Emeric Vigier6119d782012-09-21 18:04:14 -040075
alision43a9b362013-05-01 16:30:15 -040076 private BroadcastReceiver IncomingReceiver = new BroadcastReceiver() {
77
78 @Override
79 public void onReceive(Context context, Intent intent) {
80 // Get instance of Vibrator from current Context
81
alision84813a12013-05-27 17:40:39 -040082 if (intent.getAction().contentEquals(ConfigurationManagerCallback.ACCOUNT_STATE_CHANGED)) {
83 Log.i(TAG, "Received" + intent.getAction());
84 } else if (intent.getAction().contentEquals(ConfigurationManagerCallback.ACCOUNTS_LOADED)) {
85 Log.i(TAG, "Received" + intent.getAction());
86 } else if (intent.getAction().contentEquals(ConfigurationManagerCallback.ACCOUNTS_CHANGED)) {
87 Log.i(TAG, "Received" + intent.getAction());
88 } else if (intent.getAction().contentEquals(CallManagerCallBack.INCOMING_TEXT)) {
89 Log.i(TAG, "Received" + intent.getAction());
90 sendBroadcast(intent);
91 } else if (intent.getAction().contentEquals(CallManagerCallBack.INCOMING_CALL)) {
alisionfde875f2013-05-28 17:01:54 -040092 Bundle b = intent.getBundleExtra("com.savoirfairelinux.sflphone.service.newcall");
alision85704182013-05-29 15:23:03 -040093
alisionfde875f2013-05-28 17:01:54 -040094 SipCall.SipCallBuilder callBuilder = SipCall.SipCallBuilder.getInstance();
alision85704182013-05-29 15:23:03 -040095 callBuilder.startCallCreation(b.getString("CallID")).setAccountID(b.getString("AccountID"))
96 .setCallState(SipCall.state.CALL_STATE_RINGING).setCallType(SipCall.state.CALL_TYPE_INCOMING);
alisionfde875f2013-05-28 17:01:54 -040097 callBuilder.addContact(CallContact.ContactBuilder.buildUnknownContact(b.getString("From")));
alision85704182013-05-29 15:23:03 -040098
alision85992112013-05-29 12:18:08 -040099 Intent toSend = new Intent(CallManagerCallBack.INCOMING_CALL);
alisionfde875f2013-05-28 17:01:54 -0400100 try {
101 SipCall newCall = callBuilder.build();
alision85704182013-05-29 15:23:03 -0400102 toSend.putExtra("newcall", newCall);
alisionfde875f2013-05-28 17:01:54 -0400103 current_calls.put(newCall.getCallId(), newCall);
104 sendBroadcast(toSend);
105 } catch (Exception e) {
106 Log.e(TAG, e.toString());
107 }
alision85704182013-05-29 15:23:03 -0400108
alision84813a12013-05-27 17:40:39 -0400109 } else if (intent.getAction().contentEquals(CallManagerCallBack.CALL_STATE_CHANGED)) {
alision85704182013-05-29 15:23:03 -0400110
alisionfde875f2013-05-28 17:01:54 -0400111 Bundle b = intent.getBundleExtra("com.savoirfairelinux.sflphone.service.newstate");
112 String newState = b.getString("State");
113 if (newState.equals("INCOMING")) {
alision85704182013-05-29 15:23:03 -0400114 current_calls.get(b.getString("CallID")).setCallState(SipCall.state.CALL_STATE_INCOMING);
alisionfde875f2013-05-28 17:01:54 -0400115 } else if (newState.equals("RINGING")) {
alision85704182013-05-29 15:23:03 -0400116 current_calls.get(b.getString("CallID")).setCallState(SipCall.state.CALL_STATE_RINGING);
alisionfde875f2013-05-28 17:01:54 -0400117 } else if (newState.equals("CURRENT")) {
alision85704182013-05-29 15:23:03 -0400118 current_calls.get(b.getString("CallID")).setCallState(SipCall.state.CALL_STATE_CURRENT);
alisionfde875f2013-05-28 17:01:54 -0400119 } else if (newState.equals("HUNGUP")) {
120 current_calls.remove(b.getString("CallID"));
121 } else if (newState.equals("BUSY")) {
122 current_calls.remove(b.getString("CallID"));
123 } else if (newState.equals("FAILURE")) {
124 current_calls.remove(b.getString("CallID"));
125 } else if (newState.equals("HOLD")) {
alision85704182013-05-29 15:23:03 -0400126 current_calls.get(b.getString("CallID")).setCallState(SipCall.state.CALL_STATE_HOLD);
alisionfde875f2013-05-28 17:01:54 -0400127 } else if (newState.equals("UNHOLD")) {
alision85704182013-05-29 15:23:03 -0400128 current_calls.get(b.getString("CallID")).setCallState(SipCall.state.CALL_STATE_CURRENT);
alisionfde875f2013-05-28 17:01:54 -0400129 } else {
alision85704182013-05-29 15:23:03 -0400130 current_calls.get(b.getString("CallID")).setCallState(SipCall.state.CALL_STATE_NONE);
alisionfde875f2013-05-28 17:01:54 -0400131 }
alision85704182013-05-29 15:23:03 -0400132
alision84813a12013-05-27 17:40:39 -0400133 sendBroadcast(intent);
134 } else if (intent.getAction().contentEquals(CallManagerCallBack.NEW_CALL_CREATED)) {
135 Log.i(TAG, "Received" + intent.getAction());
136 Vibrator mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
137 mVibrator.vibrate(300);
alision43a9b362013-05-01 16:30:15 -0400138 }
139
140 }
141 };
142
143 @Override
144 public boolean onUnbind(Intent i) {
145 super.onUnbind(i);
146 Log.i(TAG, "onUnbind(intent)");
147 return false;
148
149 }
150
151 /* called once by startService() */
152 @Override
153 public void onCreate() {
154 Log.i(TAG, "onCreated");
155 super.onCreate();
156
157 sflphoneApp = (SFLphoneApplication) getApplication();
158 sipServiceThread = new SipServiceThread();
159
160 IntentFilter callFilter = new IntentFilter(CallManagerCallBack.CALL_STATE_CHANGED);
161 callFilter.addAction(CallManagerCallBack.INCOMING_CALL);
162 callFilter.addAction(CallManagerCallBack.NEW_CALL_CREATED);
alision4a0eb092013-05-07 13:52:03 -0400163 callFilter.addAction(ConfigurationManagerCallback.ACCOUNT_STATE_CHANGED);
164 callFilter.addAction(ConfigurationManagerCallback.ACCOUNTS_CHANGED);
165 callFilter.addAction(ConfigurationManagerCallback.ACCOUNTS_LOADED);
alision04a00182013-05-10 17:05:29 -0400166 callFilter.addAction(CallManagerCallBack.INCOMING_TEXT);
167
alision43a9b362013-05-01 16:30:15 -0400168 LocalBroadcastManager.getInstance(this).registerReceiver(IncomingReceiver, callFilter);
169 getExecutor().execute(new StartRunnable());
170 }
171
172 /* called for each startService() */
173 @Override
174 public int onStartCommand(Intent intent, int flags, int startId) {
175 Log.i(TAG, "onStarted");
176 super.onStartCommand(intent, flags, startId);
177
178 if (!runFlag) {
179 sipServiceThread.start();
180 runFlag = true;
181 sflphoneApp.setServiceRunning(true);
182 Toast.makeText(this, "Sflphone Service started", Toast.LENGTH_SHORT).show();
183 }
184
185 return START_STICKY; /* started and stopped explicitly */
186 }
187
188 @Override
189 public void onDestroy() {
190 /* called once by stopService() */
191 sipServiceThread.interrupt();
192 sipServiceThread = null;
193 runFlag = false;
194 sflphoneApp.setServiceRunning(false);
195 Toast.makeText(this, "Sflphone Service stopped", Toast.LENGTH_SHORT).show();
196 super.onDestroy();
197
198 Log.i(TAG, "onDestroyed");
199 }
200
201 @Override
202 public IBinder onBind(Intent arg0) {
203 Log.i(TAG, "onBound");
204 return mBinder;
205 }
206
207 private static Looper createLooper() {
208 if (executorThread == null) {
209 Log.d(TAG, "Creating new handler thread");
210 // ADT gives a fake warning due to bad parse rule.
211 executorThread = new HandlerThread("SipService.Executor");
212 executorThread.start();
213 }
214 return executorThread.getLooper();
215 }
216
217 public SipServiceExecutor getExecutor() {
218 // create mExecutor lazily
219 if (mExecutor == null) {
220 mExecutor = new SipServiceExecutor(this);
221 }
222 return mExecutor;
223 }
224
225 // Executes immediate tasks in a single executorThread.
226 public static class SipServiceExecutor extends Handler {
227 WeakReference<SipService> handlerService;
228
229 SipServiceExecutor(SipService s) {
230 super(createLooper());
231 handlerService = new WeakReference<SipService>(s);
232 }
233
234 public void execute(Runnable task) {
235 // TODO: add wakelock
236 Message.obtain(this, 0/* don't care */, task).sendToTarget();
237 }
238
239 @Override
240 public void handleMessage(Message msg) {
241 if (msg.obj instanceof Runnable) {
242 executeInternal((Runnable) msg.obj);
243 } else {
244 Log.w(TAG, "can't handle msg: " + msg);
245 }
246 }
247
248 private void executeInternal(Runnable task) {
249 try {
250 task.run();
251 } catch (Throwable t) {
252 Log.e(TAG, "run task: " + task, t);
253 }
254 }
255 }
256
257 private void startPjSipStack() throws SameThreadException {
258 if (isPjSipStackStarted)
259 return;
260
261 try {
262 System.loadLibrary("gnustl_shared");
263 System.loadLibrary("expat");
264 System.loadLibrary("yaml");
265 System.loadLibrary("ccgnu2");
266 System.loadLibrary("crypto");
267 System.loadLibrary("ssl");
268 System.loadLibrary("ccrtp1");
269 System.loadLibrary("dbus");
270 System.loadLibrary("dbus-c++-1");
271 System.loadLibrary("samplerate");
272 System.loadLibrary("codec_ulaw");
273 System.loadLibrary("codec_alaw");
alisiond8c83882013-05-17 17:00:42 -0400274 System.loadLibrary("codec_g722");
alision43a9b362013-05-01 16:30:15 -0400275 System.loadLibrary("speexresampler");
276 System.loadLibrary("sflphone");
277 isPjSipStackStarted = true;
278 } catch (UnsatisfiedLinkError e) {
279 Log.e(TAG, "Problem with the current Pj stack...", e);
280 isPjSipStackStarted = false;
281 return;
282 } catch (Exception e) {
283 Log.e(TAG, "Problem with the current Pj stack...", e);
284 }
285
286 /* get unique instance of managerImpl */
287 managerImpl = SFLPhoneservice.instance();
288
289 /* set static AppPath before calling manager.init */
290 managerImpl.setPath(sflphoneApp.getAppPath());
291
292 callManagerJNI = new CallManagerJNI();
293 callManagerCallBack = new CallManagerCallBack(this);
294 SFLPhoneservice.setCallbackObject(callManagerCallBack);
295
296 configurationManagerJNI = new ConfigurationManagerJNI();
297 configurationManagerCallback = new ConfigurationManagerCallback(this);
298 SFLPhoneservice.setConfigurationCallbackObject(configurationManagerCallback);
299
300 managerImpl.init("");
301 return;
302 }
303
304 // Enforce same thread contract to ensure we do not call from somewhere else
305 public class SameThreadException extends Exception {
306 private static final long serialVersionUID = -905639124232613768L;
307
308 public SameThreadException() {
309 super("Should be launched from a single worker thread");
310 }
311 }
312
313 public abstract static class SipRunnable implements Runnable {
314 protected abstract void doRun() throws SameThreadException, RemoteException;
315
316 public void run() {
317 try {
318 doRun();
319 } catch (SameThreadException e) {
320 Log.e(TAG, "Not done from same thread");
321 } catch (RemoteException e) {
322 Log.e(TAG, e.toString());
323 }
324 }
325 }
326
327 public abstract static class SipRunnableWithReturn implements Runnable {
328 Object obj = null;
329 boolean done = false;
330
331 protected abstract Object doRun() throws SameThreadException;
332
333 public Object getVal() {
334 return obj;
335 }
336
337 public boolean isDone() {
338 return done;
339 }
340
341 public void run() {
342 try {
343 obj = doRun();
344 done = true;
345 } catch (SameThreadException e) {
346 Log.e(TAG, "Not done from same thread");
347 }
348 }
349 }
350
351 class StartRunnable extends SipRunnable {
352 @Override
353 protected void doRun() throws SameThreadException {
354 startPjSipStack();
355 }
356 }
357
358 private class SipServiceThread extends Thread {
359
360 public SipServiceThread() {
361 super("sipServiceThread");
362 }
363
364 @Override
365 public void run() {
366 Log.i(TAG, "SipService thread running...");
367 SipService sipService = SipService.this;
368 while (sipService.runFlag) {
369 try {
370 Thread.sleep(DELAY);
371 } catch (InterruptedException e) {
372 sipService.runFlag = false;
373 Log.w(TAG, "service thread interrupted!");
374 }
375 }
376 }
377 }
378
379 /* ************************************
380 *
381 * Implement public interface for the service
382 *
383 *
384 * **********************************
385 */
Emeric Vigier6119d782012-09-21 18:04:14 -0400386 private final ISipService.Stub mBinder = new ISipService.Stub() {
387
388 @Override
alisionfde875f2013-05-28 17:01:54 -0400389 public void placeCall(final SipCall call) {
Emeric Vigier6119d782012-09-21 18:04:14 -0400390 getExecutor().execute(new SipRunnable() {
391 @Override
392 protected void doRun() throws SameThreadException {
393 Log.i(TAG, "SipService.placeCall() thread running...");
alisionfde875f2013-05-28 17:01:54 -0400394 callManagerJNI.placeCall(call.getAccountID(), call.getCallId(), call.getContacts().get(0).getPhones().get(0).getNumber());
395 current_calls.put(call.getCallId(), call);
Emeric Vigier6119d782012-09-21 18:04:14 -0400396 }
397 });
398 }
399
400 @Override
401 public void refuse(final String callID) {
402 getExecutor().execute(new SipRunnable() {
403 @Override
404 protected void doRun() throws SameThreadException {
405 Log.i(TAG, "SipService.refuse() thread running...");
406 callManagerJNI.refuse(callID);
407 }
408 });
409 }
410
411 @Override
412 public void accept(final String callID) {
413 getExecutor().execute(new SipRunnable() {
414 @Override
415 protected void doRun() throws SameThreadException {
416 Log.i(TAG, "SipService.placeCall() thread running...");
417 callManagerJNI.accept(callID);
418 }
419 });
420 }
421
422 @Override
423 public void hangUp(final String callID) {
424 getExecutor().execute(new SipRunnable() {
425 @Override
426 protected void doRun() throws SameThreadException {
427 Log.i(TAG, "SipService.hangUp() thread running...");
428 callManagerJNI.hangUp(callID);
429 }
430 });
431 }
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400432
433 @Override
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400434 public void hold(final String callID) {
435 getExecutor().execute(new SipRunnable() {
436 @Override
437 protected void doRun() throws SameThreadException {
438 Log.i(TAG, "SipService.hold() thread running...");
439 callManagerJNI.hold(callID);
440 }
441 });
442 }
443
444 @Override
445 public void unhold(final String callID) {
446 getExecutor().execute(new SipRunnable() {
447 @Override
448 protected void doRun() throws SameThreadException {
449 Log.i(TAG, "SipService.unhold() thread running...");
450 callManagerJNI.unhold(callID);
451 }
452 });
453 }
454
455 @Override
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400456 public void setAudioPlugin(final String audioPlugin) {
457 getExecutor().execute(new SipRunnable() {
alision371b77e2013-04-23 14:51:26 -0400458 @Override
459 protected void doRun() throws SameThreadException {
460 Log.i(TAG, "SipService.setAudioPlugin() thread running...");
461 configurationManagerJNI.setAudioPlugin(audioPlugin);
462 }
Alexandre Savard31d27c62012-10-04 16:05:08 -0400463 });
464 }
465
466 @Override
467 public String getCurrentAudioOutputPlugin() {
468 class CurrentAudioPlugin extends SipRunnableWithReturn {
469 @Override
470 protected String doRun() throws SameThreadException {
471 Log.i(TAG, "SipService.getCurrentAudioOutputPlugin() thread running...");
472 return configurationManagerJNI.getCurrentAudioOutputPlugin();
473 }
alision371b77e2013-04-23 14:51:26 -0400474 }
475 ;
Alexandre Savard31d27c62012-10-04 16:05:08 -0400476
477 CurrentAudioPlugin runInstance = new CurrentAudioPlugin();
478 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400479 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400480 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400481 }
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400482 return (String) runInstance.getVal();
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400483 }
Alexandre Savard713a34d2012-09-26 15:50:41 -0400484
485 @Override
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400486 public ArrayList<String> getAccountList() {
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400487 class AccountList extends SipRunnableWithReturn {
488 @Override
489 protected StringVect doRun() throws SameThreadException {
490 Log.i(TAG, "SipService.getAccountList() thread running...");
491 return configurationManagerJNI.getAccountList();
492 }
alision371b77e2013-04-23 14:51:26 -0400493 }
494 ;
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400495 AccountList runInstance = new AccountList();
496 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400497 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400498 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400499 }
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400500 StringVect swigvect = (StringVect) runInstance.getVal();
501
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400502 ArrayList<String> nativelist = new ArrayList<String>();
Alexandre Savard52a72522012-09-27 16:40:13 -0400503
alision371b77e2013-04-23 14:51:26 -0400504 for (int i = 0; i < swigvect.size(); i++)
505 nativelist.add(swigvect.get(i));
Alexandre Savard52a72522012-09-27 16:40:13 -0400506
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400507 return nativelist;
alision371b77e2013-04-23 14:51:26 -0400508 }
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
538 @Override
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400539 public void setAccountDetails(final String accountId, Map map) {
alision371b77e2013-04-23 14:51:26 -0400540 HashMap<String, String> nativemap = (HashMap<String, String>) map;
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400541
Alexandre Savard3bbb4792012-10-05 11:30:01 -0400542 final StringMap swigmap = AccountDetailsHandler.convertFromNativeToSwig(nativemap);
Alexandre Savard718d49f2012-10-02 15:17:13 -0400543
Alexandre Savard7a2b2202012-10-04 17:07:33 -0400544 getExecutor().execute(new SipRunnable() {
545 @Override
546 protected void doRun() throws SameThreadException {
547 Log.i(TAG, "SipService.setAccountDetails() thread running...");
548 configurationManagerJNI.setAccountDetails(accountId, swigmap);
549 }
550 });
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400551 }
552
Alexandre Savard46036572012-10-05 13:56:49 -0400553 @Override
554 public String addAccount(Map map) {
555 class AddAccount extends SipRunnableWithReturn {
556 StringMap map;
alision371b77e2013-04-23 14:51:26 -0400557
558 AddAccount(StringMap m) {
559 map = m;
560 }
561
Alexandre Savard46036572012-10-05 13:56:49 -0400562 @Override
563 protected String doRun() throws SameThreadException {
564 Log.i(TAG, "SipService.getAccountDetails() thread running...");
565 return configurationManagerJNI.addAccount(map);
566 }
alision371b77e2013-04-23 14:51:26 -0400567 }
Alexandre Savard46036572012-10-05 13:56:49 -0400568
alision371b77e2013-04-23 14:51:26 -0400569 final StringMap swigmap = AccountDetailsHandler.convertFromNativeToSwig((HashMap<String, String>) map);
Alexandre Savard46036572012-10-05 13:56:49 -0400570
571 AddAccount runInstance = new AddAccount(swigmap);
572 getExecutor().execute(runInstance);
alision371b77e2013-04-23 14:51:26 -0400573 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400574 // Log.e(TAG, "Waiting for Nofing");
alision371b77e2013-04-23 14:51:26 -0400575 }
Alexandre Savard46036572012-10-05 13:56:49 -0400576 String accountId = (String) runInstance.getVal();
577
578 return accountId;
579 }
580
581 @Override
582 public void removeAccount(final String accountId) {
583 getExecutor().execute(new SipRunnable() {
584 @Override
585 protected void doRun() throws SameThreadException {
586 Log.i(TAG, "SipService.setAccountDetails() thread running...");
587 configurationManagerJNI.removeAccount(accountId);
588 }
589 });
590 }
alision5f899632013-04-22 17:26:56 -0400591
alisione2a38e12013-04-25 14:20:20 -0400592 @Override
593 public ArrayList<HashMap<String, String>> getHistory() throws RemoteException {
594 class History extends SipRunnableWithReturn {
595
596 @Override
597 protected VectMap doRun() throws SameThreadException {
598 Log.i(TAG, "SipService.getHistory() thread running...");
alision7f18fc82013-05-01 09:37:33 -0400599
alisione2a38e12013-04-25 14:20:20 -0400600 return configurationManagerJNI.getHistory();
601 }
602 }
603
604 History runInstance = new History();
605 getExecutor().execute(runInstance);
606 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400607 // Log.w(TAG, "Waiting for getHistory");
alisione2a38e12013-04-25 14:20:20 -0400608 }
609 VectMap swigmap = (VectMap) runInstance.getVal();
610
611 ArrayList<HashMap<String, String>> nativemap = HistoryHandler.convertSwigToNative(swigmap);
612
613 return nativemap;
614 }
alision7f18fc82013-05-01 09:37:33 -0400615
alision43a9b362013-05-01 16:30:15 -0400616 /*************************
617 * Transfer related API
618 *************************/
619
alision7f18fc82013-05-01 09:37:33 -0400620 @Override
621 public void transfer(final String callID, final String to) throws RemoteException {
622 getExecutor().execute(new SipRunnable() {
623 @Override
624 protected void doRun() throws SameThreadException, RemoteException {
625 Log.i(TAG, "SipService.transfer() thread running...");
626 if (callManagerJNI.transfer(callID, to)) {
627 Bundle bundle = new Bundle();
628 bundle.putString("CallID", callID);
629 bundle.putString("State", "HUNGUP");
630 Intent intent = new Intent(CallManagerCallBack.CALL_STATE_CHANGED);
alision43a9b362013-05-01 16:30:15 -0400631 intent.putExtra(CallManagerCallBack.SIGNAL_NAME, CallManagerCallBack.CALL_STATE_CHANGED);
alision7f18fc82013-05-01 09:37:33 -0400632 intent.putExtra("com.savoirfairelinux.sflphone.service.newstate", bundle);
alision84813a12013-05-27 17:40:39 -0400633 sendBroadcast(intent);
alision7f18fc82013-05-01 09:37:33 -0400634 } else
635 Log.i(TAG, "NOT OK");
636 }
637 });
638
639 }
alision43a9b362013-05-01 16:30:15 -0400640
alision7f18fc82013-05-01 09:37:33 -0400641 @Override
642 public void attendedTransfer(final String transferID, final String targetID) throws RemoteException {
643 getExecutor().execute(new SipRunnable() {
644 @Override
645 protected void doRun() throws SameThreadException, RemoteException {
alision43a9b362013-05-01 16:30:15 -0400646 Log.i(TAG, "SipService.attendedTransfer() thread running...");
alision7f18fc82013-05-01 09:37:33 -0400647 if (callManagerJNI.attendedTransfer(transferID, targetID)) {
648 Log.i(TAG, "OK");
alision7f18fc82013-05-01 09:37:33 -0400649 } else
650 Log.i(TAG, "NOT OK");
651 }
652 });
alision43a9b362013-05-01 16:30:15 -0400653
654 }
655
656 /*************************
657 * Conference related API
658 *************************/
659
660 @Override
661 public void removeConference(final String confID) throws RemoteException {
662 getExecutor().execute(new SipRunnable() {
663 @Override
664 protected void doRun() throws SameThreadException, RemoteException {
665 Log.i(TAG, "SipService.createConference() thread running...");
666 callManagerJNI.removeConference(confID);
667 }
668 });
669
alision7f18fc82013-05-01 09:37:33 -0400670 }
671
672 @Override
alision43a9b362013-05-01 16:30:15 -0400673 public void joinParticipant(final String sel_callID, final String drag_callID) throws RemoteException {
674 getExecutor().execute(new SipRunnable() {
675 @Override
676 protected void doRun() throws SameThreadException, RemoteException {
677 Log.i(TAG, "SipService.joinParticipant() thread running...");
678 callManagerJNI.joinParticipant(sel_callID, drag_callID);
679 }
680 });
681
alision7f18fc82013-05-01 09:37:33 -0400682 }
683
684 @Override
alision43a9b362013-05-01 16:30:15 -0400685 public void createConfFromParticipantList(final List participants) throws RemoteException {
686 getExecutor().execute(new SipRunnable() {
687 @Override
688 protected void doRun() throws SameThreadException, RemoteException {
689 Log.i(TAG, "SipService.createConfFromParticipantList() thread running...");
690 // callManagerJNI.createConfFromParticipantList(participants);
691 }
692 });
693
alision7f18fc82013-05-01 09:37:33 -0400694 }
695
696 @Override
alision43a9b362013-05-01 16:30:15 -0400697 public void addParticipant(final String callID, final String confID) throws RemoteException {
698 getExecutor().execute(new SipRunnable() {
699 @Override
700 protected void doRun() throws SameThreadException, RemoteException {
701 Log.i(TAG, "SipService.addParticipant() thread running...");
702 callManagerJNI.addParticipant(callID, confID);
703 }
704 });
705
alision7f18fc82013-05-01 09:37:33 -0400706 }
707
708 @Override
alision43a9b362013-05-01 16:30:15 -0400709 public void addMainParticipant(final String confID) throws RemoteException {
710 getExecutor().execute(new SipRunnable() {
711 @Override
712 protected void doRun() throws SameThreadException, RemoteException {
713 Log.i(TAG, "SipService.addMainParticipant() thread running...");
714 callManagerJNI.addMainParticipant(confID);
715 }
716 });
717
alision7f18fc82013-05-01 09:37:33 -0400718 }
719
720 @Override
alision43a9b362013-05-01 16:30:15 -0400721 public void detachParticipant(final String callID) throws RemoteException {
722 getExecutor().execute(new SipRunnable() {
723 @Override
724 protected void doRun() throws SameThreadException, RemoteException {
725 Log.i(TAG, "SipService.detachParticipant() thread running...");
726 callManagerJNI.detachParticipant(callID);
727 }
728 });
729
alision7f18fc82013-05-01 09:37:33 -0400730 }
731
732 @Override
alision43a9b362013-05-01 16:30:15 -0400733 public void joinConference(final String sel_confID, final String drag_confID) throws RemoteException {
734 getExecutor().execute(new SipRunnable() {
735 @Override
736 protected void doRun() throws SameThreadException, RemoteException {
737 Log.i(TAG, "SipService.joinConference() thread running...");
738 callManagerJNI.joinConference(sel_confID, drag_confID);
739 }
740 });
741
alision7f18fc82013-05-01 09:37:33 -0400742 }
743
744 @Override
alision43a9b362013-05-01 16:30:15 -0400745 public void hangUpConference(final String confID) throws RemoteException {
746 getExecutor().execute(new SipRunnable() {
747 @Override
748 protected void doRun() throws SameThreadException, RemoteException {
749 Log.i(TAG, "SipService.joinConference() thread running...");
750 callManagerJNI.hangUpConference(confID);
751 }
752 });
753
alision7f18fc82013-05-01 09:37:33 -0400754 }
755
756 @Override
alision43a9b362013-05-01 16:30:15 -0400757 public void holdConference(final String confID) throws RemoteException {
758 getExecutor().execute(new SipRunnable() {
759 @Override
760 protected void doRun() throws SameThreadException, RemoteException {
761 Log.i(TAG, "SipService.holdConference() thread running...");
762 callManagerJNI.holdConference(confID);
763 }
764 });
765
alision7f18fc82013-05-01 09:37:33 -0400766 }
767
768 @Override
alision43a9b362013-05-01 16:30:15 -0400769 public void unholdConference(final String confID) throws RemoteException {
770 getExecutor().execute(new SipRunnable() {
771 @Override
772 protected void doRun() throws SameThreadException, RemoteException {
773 Log.i(TAG, "SipService.unholdConference() thread running...");
774 callManagerJNI.unholdConference(confID);
775 }
776 });
777
alision7f18fc82013-05-01 09:37:33 -0400778 }
779
780 @Override
781 public List getConferenceList() throws RemoteException {
alision4a0eb092013-05-07 13:52:03 -0400782 class ConfList extends SipRunnableWithReturn {
783 @Override
784 protected StringVect doRun() throws SameThreadException {
785 Log.i(TAG, "SipService.getAccountList() thread running...");
786 return callManagerJNI.getConferenceList();
787 }
788 }
789 ;
790 ConfList runInstance = new ConfList();
791 getExecutor().execute(runInstance);
792 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400793 // Log.w(TAG, "Waiting for getConferenceList");
alision4a0eb092013-05-07 13:52:03 -0400794 }
795 StringVect swigvect = (StringVect) runInstance.getVal();
796
797 ArrayList<String> nativelist = new ArrayList<String>();
798
799 for (int i = 0; i < swigvect.size(); i++)
800 nativelist.add(swigvect.get(i));
801
802 return nativelist;
alision7f18fc82013-05-01 09:37:33 -0400803 }
804
805 @Override
806 public List getParticipantList(String confID) throws RemoteException {
alision43a9b362013-05-01 16:30:15 -0400807 Log.e(TAG, "getConferenceList not implemented");
alision7f18fc82013-05-01 09:37:33 -0400808 return null;
809 }
810
811 @Override
812 public String getConferenceId(String callID) throws RemoteException {
alision43a9b362013-05-01 16:30:15 -0400813 Log.e(TAG, "getConferenceList not implemented");
alision7f18fc82013-05-01 09:37:33 -0400814 return null;
815 }
816
817 @Override
818 public Map getConferenceDetails(String callID) throws RemoteException {
alision43a9b362013-05-01 16:30:15 -0400819 Log.e(TAG, "getConferenceList not implemented");
alision7f18fc82013-05-01 09:37:33 -0400820 return null;
821 }
822
alision04a00182013-05-10 17:05:29 -0400823 @Override
824 public String getRecordPath() throws RemoteException {
825 class RecordPath extends SipRunnableWithReturn {
826
827 @Override
828 protected String doRun() throws SameThreadException {
829 Log.i(TAG, "SipService.getRecordPath() thread running...");
830 return configurationManagerJNI.getRecordPath();
831 }
832 }
833
834 RecordPath runInstance = new RecordPath();
835 getExecutor().execute(runInstance);
836 while (!runInstance.isDone()) {
alision84813a12013-05-27 17:40:39 -0400837 // Log.w(TAG, "Waiting for getRecordPath");
alision04a00182013-05-10 17:05:29 -0400838 }
839 String path = (String) runInstance.getVal();
840
841 return path;
842 }
843
844 @Override
845 public void setRecordingCall(final String id) throws RemoteException {
846 getExecutor().execute(new SipRunnable() {
847 @Override
848 protected void doRun() throws SameThreadException, RemoteException {
849 Log.i(TAG, "SipService.setRecordingCall() thread running...");
850 callManagerJNI.setRecordingCall(id);
851 }
852 });
853
854 }
855
856 @Override
857 public void setRecordPath(final String path) throws RemoteException {
858 getExecutor().execute(new SipRunnable() {
859 @Override
860 protected void doRun() throws SameThreadException, RemoteException {
861 Log.i(TAG, "SipService.setRecordingCall() thread running...");
862 configurationManagerJNI.setRecordPath(path);
863 }
864 });
865 }
866
867 @Override
868 public void sendTextMessage(final String callID, final String message, final String from) throws RemoteException {
869 getExecutor().execute(new SipRunnable() {
870 @Override
871 protected void doRun() throws SameThreadException, RemoteException {
872 Log.i(TAG, "SipService.sendTextMessage() thread running...");
873 callManagerJNI.sendTextMessage(callID, message, from);
874 }
875 });
876
877 }
878
alisiond295ec22013-05-17 10:12:13 -0400879 @Override
880 public List getAudioCodecList(String accountID) throws RemoteException {
881 class AudioCodecList extends SipRunnableWithReturn {
882
883 @Override
884 protected IntVect doRun() throws SameThreadException {
885 Log.i(TAG, "SipService.getAudioCodecList() thread running...");
886 return configurationManagerJNI.getAudioCodecList();
887 }
888 }
889
890 AudioCodecList runInstance = new AudioCodecList();
891 getExecutor().execute(runInstance);
892 while (!runInstance.isDone()) {
893 Log.w(TAG, "Waiting for getAudioCodecList");
894 }
895 IntVect swigmap = (IntVect) runInstance.getVal();
896
897 ArrayList<Integer> codecs = AudioHandler.convertSwigToNative(swigmap);
898
899 return codecs;
900 }
901
alision9f7a6ec2013-05-24 16:26:26 -0400902 @Override
alisionfde875f2013-05-28 17:01:54 -0400903 public HashMap<String, SipCall> getCallList() throws RemoteException {
alision85704182013-05-29 15:23:03 -0400904 // class CallList extends SipRunnableWithReturn {
905 //
906 // @Override
907 // protected StringVect doRun() throws SameThreadException {
908 // Log.i(TAG, "SipService.getCallList() thread running...");
909 // return callManagerJNI.getCallList();
910 // }
911 // }
912 //
913 // CallList runInstance = new CallList();
914 // getExecutor().execute(runInstance);
915 // while (!runInstance.isDone()) {
916 // Log.w(TAG, "Waiting for getAudioCodecList");
917 // }
918 // StringVect swigmap = (StringVect) runInstance.getVal();
919 //
920 // ArrayList<String> nativemap = new ArrayList<String>();
921 // for (int i = 0; i < swigmap.size(); ++i) {
922 //
923 // String t = swigmap.get(i);
924 // nativemap.add(t);
925 // }
alision9f7a6ec2013-05-24 16:26:26 -0400926
alisionfde875f2013-05-28 17:01:54 -0400927 return current_calls;
alision9f7a6ec2013-05-24 16:26:26 -0400928 }
929
alision85704182013-05-29 15:23:03 -0400930 @Override
931 public SipCall getCall(String callID) throws RemoteException {
932 return current_calls.get(callID);
933 }
934
Emeric Vigier6119d782012-09-21 18:04:14 -0400935 };
Emeric Vigiereaf2c492012-09-19 14:38:20 -0400936}