blob: 6c0fefd2030093b1f81bcb9bfe4b1d96ded39160 [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>
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 * If you own a pjsip commercial license you can also redistribute it
13 * and/or modify it under the terms of the GNU Lesser General Public License
14 * as an android library.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 */
Emeric Vigiereaf2c492012-09-19 14:38:20 -040024package com.savoirfairelinux.sflphone.service;
25
Emeric Vigier6119d782012-09-21 18:04:14 -040026import java.lang.ref.WeakReference;
27
Emeric Vigiereaf2c492012-09-19 14:38:20 -040028import android.app.Service;
29import android.content.Intent;
30import android.os.Binder;
Emeric Vigier6119d782012-09-21 18:04:14 -040031import android.os.Handler;
32import android.os.HandlerThread;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040033import android.os.IBinder;
Emeric Vigier6119d782012-09-21 18:04:14 -040034import android.os.Looper;
35import android.os.Message;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040036import android.util.Log;
37import android.widget.Toast;
38
Emeric Vigier0007dee2012-09-24 11:35:58 -040039import com.savoirfairelinux.sflphone.service.ManagerImpl;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040040import com.savoirfairelinux.sflphone.client.SFLphoneApplication;
Emeric Vigier6119d782012-09-21 18:04:14 -040041import com.savoirfairelinux.sflphone.service.ISipService;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040042
Alexandre Savard8b7d4332012-09-30 20:02:11 -040043import java.util.Map;
Alexandre Savard713a34d2012-09-26 15:50:41 -040044import java.util.HashMap;
Alexandre Savard6b85e7e2012-09-27 15:43:14 -040045import java.util.ArrayList;
Alexandre Savard713a34d2012-09-26 15:50:41 -040046
Emeric Vigiereaf2c492012-09-19 14:38:20 -040047public class SipService extends Service {
48
49 static final String TAG = "SipService";
50 static final int DELAY = 5000; /* 5 sec */
51 private boolean runFlag = false;
52 private SipServiceThread sipServiceThread;
Emeric Vigier84e05da2012-09-20 14:53:05 -040053 private SFLphoneApplication sflphoneApp;
Emeric Vigier6119d782012-09-21 18:04:14 -040054 private SipServiceExecutor mExecutor;
55 private static HandlerThread executorThread;
56 private CallManagerJNI callManagerJNI;
Emeric Vigier0007dee2012-09-24 11:35:58 -040057 private CallManagerCallBack callManagerCallBack;
Alexandre Savardc1b08fe2012-09-25 16:24:47 -040058 private ConfigurationManagerJNI configurationManagerJNI;
Emeric Vigier0007dee2012-09-24 11:35:58 -040059 private ManagerImpl managerImpl;
Emeric Vigier6119d782012-09-21 18:04:14 -040060 private boolean isPjSipStackStarted = false;
61
62 /* Implement public interface for the service */
63 private final ISipService.Stub mBinder = new ISipService.Stub() {
64
65 @Override
66 public void placeCall(final String accountID, final String callID, final String to) {
67 getExecutor().execute(new SipRunnable() {
68 @Override
69 protected void doRun() throws SameThreadException {
70 Log.i(TAG, "SipService.placeCall() thread running...");
71 callManagerJNI.placeCall(accountID, callID, to);
72 }
73 });
74 }
75
76 @Override
77 public void refuse(final String callID) {
78 getExecutor().execute(new SipRunnable() {
79 @Override
80 protected void doRun() throws SameThreadException {
81 Log.i(TAG, "SipService.refuse() thread running...");
82 callManagerJNI.refuse(callID);
83 }
84 });
85 }
86
87 @Override
88 public void accept(final String callID) {
89 getExecutor().execute(new SipRunnable() {
90 @Override
91 protected void doRun() throws SameThreadException {
92 Log.i(TAG, "SipService.placeCall() thread running...");
93 callManagerJNI.accept(callID);
94 }
95 });
96 }
97
98 @Override
99 public void hangUp(final String callID) {
100 getExecutor().execute(new SipRunnable() {
101 @Override
102 protected void doRun() throws SameThreadException {
103 Log.i(TAG, "SipService.hangUp() thread running...");
104 callManagerJNI.hangUp(callID);
105 }
106 });
107 }
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400108
109 @Override
110 public void setAudioPlugin(final String audioPlugin) {
111 getExecutor().execute(new SipRunnable() {
112 @Override
113 protected void doRun() throws SameThreadException {
114 Log.i(TAG, "SipService.setAudioPlugin() thread running...");
115 configurationManagerJNI.setAudioPlugin(audioPlugin);
116 }
Alexandre Savard31d27c62012-10-04 16:05:08 -0400117 });
118 }
119
120 @Override
121 public String getCurrentAudioOutputPlugin() {
122 class CurrentAudioPlugin extends SipRunnableWithReturn {
123 @Override
124 protected String doRun() throws SameThreadException {
125 Log.i(TAG, "SipService.getCurrentAudioOutputPlugin() thread running...");
126 return configurationManagerJNI.getCurrentAudioOutputPlugin();
127 }
128 };
129
130 CurrentAudioPlugin runInstance = new CurrentAudioPlugin();
131 getExecutor().execute(runInstance);
132 while(!runInstance.isDone()) {}
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400133 return (String) runInstance.getVal();
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400134 }
Alexandre Savard713a34d2012-09-26 15:50:41 -0400135
136 @Override
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400137 public ArrayList<String> getAccountList() {
138 StringVect swigvect = configurationManagerJNI.getAccountList();
139 ArrayList<String> nativelist = new ArrayList<String>();
Alexandre Savard52a72522012-09-27 16:40:13 -0400140
141 for(int i = 0; i < swigvect.size(); i++)
142 nativelist.add(swigvect.get(i));
143
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400144 return nativelist;
145 }
146
147 @Override
Alexandre Savard713a34d2012-09-26 15:50:41 -0400148 public HashMap<String,String> getAccountDetails(final String accountID) {
Alexandre Savard7a902bc2012-10-04 16:32:35 -0400149 class AccountDetails extends SipRunnableWithReturn {
150 private String id;
151 AccountDetails(String accountId) { id = accountId; }
152 @Override
153 protected StringMap doRun() throws SameThreadException {
154 Log.i(TAG, "SipService.getCurrentAudioOutputPlugin() thread running...");
155 return configurationManagerJNI.getAccountDetails(id);
156 }
157 };
158
159 AccountDetails runInstance = new AccountDetails(accountID);
160 getExecutor().execute(runInstance);
161 while(!runInstance.isDone()) {}
162 StringMap swigmap = (StringMap) runInstance.getVal();
Alexandre Savard713a34d2012-09-26 15:50:41 -0400163
164 HashMap<String, String> nativemap = new HashMap<String, String>();
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400165
166 nativemap.put(ServiceConstants.CONFIG_ACCOUNT_ALIAS, swigmap.get(ServiceConstants.CONFIG_ACCOUNT_ALIAS));
167 nativemap.put(ServiceConstants.CONFIG_ACCOUNT_HOSTNAME, swigmap.get(ServiceConstants.CONFIG_ACCOUNT_HOSTNAME));
168 nativemap.put(ServiceConstants.CONFIG_ACCOUNT_USERNAME, swigmap.get(ServiceConstants.CONFIG_ACCOUNT_USERNAME));
169 nativemap.put(ServiceConstants.CONFIG_ACCOUNT_ROUTESET, swigmap.get(ServiceConstants.CONFIG_ACCOUNT_ROUTESET));
170 nativemap.put(ServiceConstants.CONFIG_ACCOUNT_REGISTRATION_EXPIRE, swigmap.get(ServiceConstants.CONFIG_ACCOUNT_REGISTRATION_EXPIRE));
Alexandre Savard718d49f2012-10-02 15:17:13 -0400171
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400172 nativemap.put(ServiceConstants.CONFIG_LOCAL_INTERFACE, swigmap.get(ServiceConstants.CONFIG_LOCAL_INTERFACE));
173 nativemap.put(ServiceConstants.CONFIG_STUN_SERVER, swigmap.get(ServiceConstants.CONFIG_STUN_SERVER));
174 nativemap.put(ServiceConstants.CONFIG_TLS_ENABLE, swigmap.get(ServiceConstants.CONFIG_TLS_ENABLE));
175 nativemap.put(ServiceConstants.CONFIG_SRTP_ENABLE, swigmap.get(ServiceConstants.CONFIG_SRTP_ENABLE));
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400176 nativemap.put(ServiceConstants.CONFIG_ACCOUNT_TYPE, swigmap.get(ServiceConstants.CONFIG_ACCOUNT_TYPE));
Alexandre Savard718d49f2012-10-02 15:17:13 -0400177
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400178 nativemap.put(ServiceConstants.CONFIG_ACCOUNT_MAILBOX, swigmap.get(ServiceConstants.CONFIG_ACCOUNT_MAILBOX));
179 nativemap.put(ServiceConstants.CONFIG_ACCOUNT_ENABLE, swigmap.get(ServiceConstants.CONFIG_ACCOUNT_ENABLE));
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400180 nativemap.put(ServiceConstants.CONFIG_ACCOUNT_REGISTRATION_STATUS, swigmap.get(ServiceConstants.CONFIG_ACCOUNT_REGISTRATION_STATUS));
181 nativemap.put(ServiceConstants.CONFIG_ACCOUNT_REGISTRATION_STATE_CODE, swigmap.get(ServiceConstants.CONFIG_ACCOUNT_REGISTRATION_STATE_CODE));
182 nativemap.put(ServiceConstants.CONFIG_ACCOUNT_REGISTRATION_STATE_DESC, swigmap.get(ServiceConstants.CONFIG_ACCOUNT_REGISTRATION_STATE_DESC));
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400183
Alexandre Savarda518da72012-10-01 13:51:56 -0400184 nativemap.put(ServiceConstants.CONFIG_ACCOUNT_AUTOANSWER, swigmap.get(ServiceConstants.CONFIG_ACCOUNT_AUTOANSWER));
185 nativemap.put(ServiceConstants.CONFIG_ACCOUNT_DTMF_TYPE, swigmap.get(ServiceConstants.CONFIG_ACCOUNT_DTMF_TYPE));
186 nativemap.put(ServiceConstants.CONFIG_KEEP_ALIVE_ENABLED, swigmap.get(ServiceConstants.CONFIG_KEEP_ALIVE_ENABLED));
187 nativemap.put(ServiceConstants.CONFIG_LOCAL_PORT, swigmap.get(ServiceConstants.CONFIG_LOCAL_PORT));
188 nativemap.put(ServiceConstants.CONFIG_PUBLISHED_ADDRESS, swigmap.get(ServiceConstants.CONFIG_PUBLISHED_ADDRESS));
189
190 nativemap.put(ServiceConstants.CONFIG_PUBLISHED_PORT, swigmap.get(ServiceConstants.CONFIG_PUBLISHED_PORT));
191 nativemap.put(ServiceConstants.CONFIG_PUBLISHED_SAMEAS_LOCAL, swigmap.get(ServiceConstants.CONFIG_PUBLISHED_SAMEAS_LOCAL));
192 nativemap.put(ServiceConstants.CONFIG_RINGTONE_ENABLED, swigmap.get(ServiceConstants.CONFIG_RINGTONE_ENABLED));
193 nativemap.put(ServiceConstants.CONFIG_RINGTONE_PATH, swigmap.get(ServiceConstants.CONFIG_RINGTONE_PATH));
194 nativemap.put(ServiceConstants.CONFIG_ACCOUNT_USERAGENT, swigmap.get(ServiceConstants.CONFIG_ACCOUNT_USERAGENT));
195
196 nativemap.put(ServiceConstants.CONFIG_SRTP_KEY_EXCHANGE, swigmap.get(ServiceConstants.CONFIG_SRTP_KEY_EXCHANGE));
197 nativemap.put(ServiceConstants.CONFIG_SRTP_RTP_FALLBACK, swigmap.get(ServiceConstants.CONFIG_SRTP_RTP_FALLBACK));
198 nativemap.put(ServiceConstants.CONFIG_STUN_ENABLE, swigmap.get(ServiceConstants.CONFIG_STUN_ENABLE));
199 nativemap.put(ServiceConstants.CONFIG_TLS_CERTIFICATE_FILE, swigmap.get(ServiceConstants.CONFIG_TLS_CERTIFICATE_FILE));
200 nativemap.put(ServiceConstants.CONFIG_TLS_CA_LIST_FILE, swigmap.get(ServiceConstants.CONFIG_TLS_CA_LIST_FILE));
201
202 nativemap.put(ServiceConstants.CONFIG_TLS_CIPHERS, swigmap.get(ServiceConstants.CONFIG_TLS_CIPHERS));
203 nativemap.put(ServiceConstants.CONFIG_TLS_LISTENER_PORT, swigmap.get(ServiceConstants.CONFIG_TLS_LISTENER_PORT));
204 nativemap.put(ServiceConstants.CONFIG_TLS_METHOD, swigmap.get(ServiceConstants.CONFIG_TLS_METHOD));
205 nativemap.put(ServiceConstants.CONFIG_TLS_NEGOTIATION_TIMEOUT_MSEC, swigmap.get(ServiceConstants.CONFIG_TLS_NEGOTIATION_TIMEOUT_MSEC));
206 nativemap.put(ServiceConstants.CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC, swigmap.get(ServiceConstants.CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC));
207
208 nativemap.put(ServiceConstants.CONFIG_TLS_PASSWORD, swigmap.get(ServiceConstants.CONFIG_TLS_PASSWORD));
209 nativemap.put(ServiceConstants.CONFIG_TLS_PRIVATE_KEY_FILE, swigmap.get(ServiceConstants.CONFIG_TLS_PRIVATE_KEY_FILE));
210 nativemap.put(ServiceConstants.CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE, swigmap.get(ServiceConstants.CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE));
211 nativemap.put(ServiceConstants.CONFIG_TLS_SERVER_NAME, swigmap.get(ServiceConstants.CONFIG_TLS_SERVER_NAME));
212 nativemap.put(ServiceConstants.CONFIG_TLS_VERIFY_CLIENT, swigmap.get(ServiceConstants.CONFIG_TLS_VERIFY_CLIENT));
213
214 nativemap.put(ServiceConstants.CONFIG_TLS_VERIFY_SERVER, swigmap.get(ServiceConstants.CONFIG_TLS_VERIFY_SERVER));
215 nativemap.put(ServiceConstants.CONFIG_ZRTP_DISPLAY_SAS, swigmap.get(ServiceConstants.CONFIG_ZRTP_DISPLAY_SAS));
216 nativemap.put(ServiceConstants.CONFIG_ZRTP_DISPLAY_SAS_ONCE, swigmap.get(ServiceConstants.CONFIG_ZRTP_DISPLAY_SAS_ONCE));
217 nativemap.put(ServiceConstants.CONFIG_ZRTP_HELLO_HASH, swigmap.get(ServiceConstants.CONFIG_ZRTP_HELLO_HASH));
218 nativemap.put(ServiceConstants.CONFIG_ZRTP_NOT_SUPP_WARNING, swigmap.get(ServiceConstants.CONFIG_ZRTP_NOT_SUPP_WARNING));
219
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400220 /*
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400221 nativemap.put(ServiceConstants.CONFIG_CREDENTIAL_NUMBER, swigmap.get(ServiceConstants.CONFIG_CREDENTIAL_NUMBER));
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400222 nativemap.put(ServiceConstants.CONFIG_ACCOUNT_PASSWORD, swigmap.get(ServiceConstants.CONFIG_ACCOUNT_PASSWORD));
223 nativemap.put(ServiceConstants.CONFIG_ACCOUNT_REALM, swigmap.get(ServiceConstants.CONFIG_ACCOUNT_REALM));
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400224 */
225
226 /*
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400227 nativemap.put(ServiceConstants.CONFIG_ACCOUNT_DEFAULT_REALM, swigmap.get(ServiceConstants.CONFIG_ACCOUNT_DEFAULT_REALM));
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400228 nativemap.put(ServiceConstants.CONFIG_INTERFACE, swigmap.get(ServiceConstants.CONFIG_INTERFACE));
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400229 nativemap.put(ServiceConstants.CONFIG_DEFAULT_INTERFACE, swigmap.get(ServiceConstants.CONFIG_DEFAULT_INTERFACE));
230 nativemap.put(ServiceConstants.CONFIG_DISPLAY_NAME, swigmap.get(ServiceConstants.CONFIG_DISPLAY_NAME));
231 nativemap.put(ServiceConstants.CONFIG_DEFAULT_ADDRESS, swigmap.get(ServiceConstants.CONFIG_DEFAULT_ADDRESS));
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400232 nativemap.put(ServiceConstants.CONFIG_SRTP_ENCRYPTION_ALGO, swigmap.get(ServiceConstants.CONFIG_SRTP_ENCRYPTION_ALGO));
Alexandre Savard6b85e7e2012-09-27 15:43:14 -0400233 */
Alexandre Savard713a34d2012-09-26 15:50:41 -0400234
235 return nativemap;
236 }
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400237
238 @Override
239 public void setAccountDetails(String accountId, Map map) {
240 HashMap<String,String> nativemap = (HashMap<String,String>) map;
241
242 StringMap swigmap = new StringMap();
243
244 swigmap.set(ServiceConstants.CONFIG_ACCOUNT_ALIAS, nativemap.get(ServiceConstants.CONFIG_ACCOUNT_ALIAS));
245 swigmap.set(ServiceConstants.CONFIG_ACCOUNT_HOSTNAME, nativemap.get(ServiceConstants.CONFIG_ACCOUNT_HOSTNAME));
246 swigmap.set(ServiceConstants.CONFIG_ACCOUNT_USERNAME, nativemap.get(ServiceConstants.CONFIG_ACCOUNT_USERNAME));
247 swigmap.set(ServiceConstants.CONFIG_ACCOUNT_ROUTESET, nativemap.get(ServiceConstants.CONFIG_ACCOUNT_ROUTESET));
248 swigmap.set(ServiceConstants.CONFIG_ACCOUNT_REGISTRATION_EXPIRE, nativemap.get(ServiceConstants.CONFIG_ACCOUNT_REGISTRATION_EXPIRE));
Alexandre Savard718d49f2012-10-02 15:17:13 -0400249
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400250 swigmap.set(ServiceConstants.CONFIG_LOCAL_INTERFACE, nativemap.get(ServiceConstants.CONFIG_LOCAL_INTERFACE));
251 swigmap.set(ServiceConstants.CONFIG_STUN_SERVER, nativemap.get(ServiceConstants.CONFIG_STUN_SERVER));
252 swigmap.set(ServiceConstants.CONFIG_TLS_ENABLE, nativemap.get(ServiceConstants.CONFIG_TLS_ENABLE));
253 swigmap.set(ServiceConstants.CONFIG_SRTP_ENABLE, nativemap.get(ServiceConstants.CONFIG_SRTP_ENABLE));
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400254 swigmap.set(ServiceConstants.CONFIG_ACCOUNT_TYPE, nativemap.get(ServiceConstants.CONFIG_ACCOUNT_TYPE));
Alexandre Savard718d49f2012-10-02 15:17:13 -0400255
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400256 swigmap.set(ServiceConstants.CONFIG_ACCOUNT_MAILBOX, nativemap.get(ServiceConstants.CONFIG_ACCOUNT_MAILBOX));
257 swigmap.set(ServiceConstants.CONFIG_ACCOUNT_ENABLE, nativemap.get(ServiceConstants.CONFIG_ACCOUNT_ENABLE));
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400258 swigmap.set(ServiceConstants.CONFIG_ACCOUNT_REGISTRATION_STATUS, nativemap.get(ServiceConstants.CONFIG_ACCOUNT_REGISTRATION_STATUS));
259 swigmap.set(ServiceConstants.CONFIG_ACCOUNT_REGISTRATION_STATE_CODE, nativemap.get(ServiceConstants.CONFIG_ACCOUNT_REGISTRATION_STATE_CODE));
260 swigmap.set(ServiceConstants.CONFIG_ACCOUNT_REGISTRATION_STATE_DESC, nativemap.get(ServiceConstants.CONFIG_ACCOUNT_REGISTRATION_STATE_DESC));
261
Alexandre Savard718d49f2012-10-02 15:17:13 -0400262 swigmap.set(ServiceConstants.CONFIG_ACCOUNT_AUTOANSWER, nativemap.get(ServiceConstants.CONFIG_ACCOUNT_AUTOANSWER));
263 swigmap.set(ServiceConstants.CONFIG_ACCOUNT_DTMF_TYPE, nativemap.get(ServiceConstants.CONFIG_ACCOUNT_DTMF_TYPE));
264 swigmap.set(ServiceConstants.CONFIG_KEEP_ALIVE_ENABLED, nativemap.get(ServiceConstants.CONFIG_KEEP_ALIVE_ENABLED));
265 swigmap.set(ServiceConstants.CONFIG_LOCAL_PORT, nativemap.get(ServiceConstants.CONFIG_LOCAL_PORT));
266 swigmap.set(ServiceConstants.CONFIG_PUBLISHED_ADDRESS, nativemap.get(ServiceConstants.CONFIG_PUBLISHED_ADDRESS));
267
268 swigmap.set(ServiceConstants.CONFIG_PUBLISHED_PORT, nativemap.get(ServiceConstants.CONFIG_PUBLISHED_PORT));
269 swigmap.set(ServiceConstants.CONFIG_PUBLISHED_SAMEAS_LOCAL, nativemap.get(ServiceConstants.CONFIG_PUBLISHED_SAMEAS_LOCAL));
270 swigmap.set(ServiceConstants.CONFIG_RINGTONE_ENABLED, nativemap.get(ServiceConstants.CONFIG_RINGTONE_ENABLED));
271 swigmap.set(ServiceConstants.CONFIG_RINGTONE_PATH, nativemap.get(ServiceConstants.CONFIG_RINGTONE_PATH));
272 swigmap.set(ServiceConstants.CONFIG_ACCOUNT_USERAGENT, nativemap.get(ServiceConstants.CONFIG_ACCOUNT_USERAGENT));
273
274 swigmap.set(ServiceConstants.CONFIG_SRTP_KEY_EXCHANGE, nativemap.get(ServiceConstants.CONFIG_SRTP_KEY_EXCHANGE));
275 swigmap.set(ServiceConstants.CONFIG_SRTP_RTP_FALLBACK, nativemap.get(ServiceConstants.CONFIG_SRTP_RTP_FALLBACK));
276 swigmap.set(ServiceConstants.CONFIG_STUN_ENABLE, nativemap.get(ServiceConstants.CONFIG_STUN_ENABLE));
277 swigmap.set(ServiceConstants.CONFIG_TLS_CERTIFICATE_FILE, nativemap.get(ServiceConstants.CONFIG_TLS_CERTIFICATE_FILE));
278 swigmap.set(ServiceConstants.CONFIG_TLS_CA_LIST_FILE, nativemap.get(ServiceConstants.CONFIG_TLS_CA_LIST_FILE));
279
280 swigmap.set(ServiceConstants.CONFIG_TLS_CIPHERS, nativemap.get(ServiceConstants.CONFIG_TLS_CIPHERS));
281 swigmap.set(ServiceConstants.CONFIG_TLS_LISTENER_PORT, nativemap.get(ServiceConstants.CONFIG_TLS_LISTENER_PORT));
282 swigmap.set(ServiceConstants.CONFIG_TLS_METHOD, nativemap.get(ServiceConstants.CONFIG_TLS_METHOD));
283 swigmap.set(ServiceConstants.CONFIG_TLS_NEGOTIATION_TIMEOUT_MSEC, nativemap.get(ServiceConstants.CONFIG_TLS_NEGOTIATION_TIMEOUT_MSEC));
284 swigmap.set(ServiceConstants.CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC, nativemap.get(ServiceConstants.CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC));
285
286 swigmap.set(ServiceConstants.CONFIG_TLS_PASSWORD, nativemap.get(ServiceConstants.CONFIG_TLS_PASSWORD));
287 swigmap.set(ServiceConstants.CONFIG_TLS_PRIVATE_KEY_FILE, nativemap.get(ServiceConstants.CONFIG_TLS_PRIVATE_KEY_FILE));
288 swigmap.set(ServiceConstants.CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE, nativemap.get(ServiceConstants.CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE));
289 swigmap.set(ServiceConstants.CONFIG_TLS_SERVER_NAME, nativemap.get(ServiceConstants.CONFIG_TLS_SERVER_NAME));
290 swigmap.set(ServiceConstants.CONFIG_TLS_VERIFY_CLIENT, nativemap.get(ServiceConstants.CONFIG_TLS_VERIFY_CLIENT));
291
292 swigmap.set(ServiceConstants.CONFIG_TLS_VERIFY_SERVER, nativemap.get(ServiceConstants.CONFIG_TLS_VERIFY_SERVER));
293 swigmap.set(ServiceConstants.CONFIG_ZRTP_DISPLAY_SAS, nativemap.get(ServiceConstants.CONFIG_ZRTP_DISPLAY_SAS));
294 swigmap.set(ServiceConstants.CONFIG_ZRTP_DISPLAY_SAS_ONCE, nativemap.get(ServiceConstants.CONFIG_ZRTP_DISPLAY_SAS_ONCE));
295 swigmap.set(ServiceConstants.CONFIG_ZRTP_HELLO_HASH, nativemap.get(ServiceConstants.CONFIG_ZRTP_HELLO_HASH));
296 swigmap.set(ServiceConstants.CONFIG_ZRTP_NOT_SUPP_WARNING, nativemap.get(ServiceConstants.CONFIG_ZRTP_NOT_SUPP_WARNING));
297
Alexandre Savard8b7d4332012-09-30 20:02:11 -0400298 configurationManagerJNI.setAccountDetails(accountId, swigmap);
299 }
300
Emeric Vigier6119d782012-09-21 18:04:14 -0400301 };
302
303 /**
304 * Class used for the client Binder. Because we know this service always
305 * runs in the same process as its clients, we don't need to deal with IPC.
306 */
307 public class LocalBinder extends Binder {
308 public SipService getService() {
309 // Return this instance of LocalService so clients can call public methods
310 return SipService.this;
311 }
312 }
Emeric Vigiereaf2c492012-09-19 14:38:20 -0400313
314 /* called once by startService() */
315 @Override
316 public void onCreate() {
317 Log.i(TAG, "onCreated");
318 super.onCreate();
Emeric Vigier6119d782012-09-21 18:04:14 -0400319 sflphoneApp = (SFLphoneApplication) getApplication();
320 sipServiceThread = new SipServiceThread();
321 getExecutor().execute(new StartRunnable());
Emeric Vigiereaf2c492012-09-19 14:38:20 -0400322 }
323
324 /* called for each startService() */
325 @Override
326 public int onStartCommand(Intent intent, int flags, int startId) {
327 Log.i(TAG, "onStarted");
328 super.onStartCommand(intent, flags, startId);
Emeric Vigier6119d782012-09-21 18:04:14 -0400329
330 runFlag = true;
331 sipServiceThread.start();
332 sflphoneApp.setServiceRunning(true);
Emeric Vigiereaf2c492012-09-19 14:38:20 -0400333 Toast.makeText(this, "Sflphone Service started", Toast.LENGTH_SHORT).show();
Emeric Vigier6119d782012-09-21 18:04:14 -0400334
Emeric Vigiereaf2c492012-09-19 14:38:20 -0400335 Log.i(TAG, "onStarted");
336 return START_STICKY; /* started and stopped explicitly */
337 }
338
339 @Override
340 public void onDestroy() {
341 /* called once by stopService() */
342 super.onDestroy();
Emeric Vigier6119d782012-09-21 18:04:14 -0400343 runFlag = false;
344 sipServiceThread.interrupt();
345 sipServiceThread = null;
346 sflphoneApp.setServiceRunning(false);
Emeric Vigiereaf2c492012-09-19 14:38:20 -0400347 Toast.makeText(this, "Sflphone Service stopped", Toast.LENGTH_SHORT).show();
348
349 Log.i(TAG, "onDestroyed");
350 }
351
352 @Override
353 public IBinder onBind(Intent arg0) {
354 Log.i(TAG, "onBound");
355 return mBinder;
356 }
357
Emeric Vigier6119d782012-09-21 18:04:14 -0400358 private static Looper createLooper() {
359 if(executorThread == null) {
360 Log.d(TAG, "Creating new handler thread");
361 // ADT gives a fake warning due to bad parse rule.
362 executorThread = new HandlerThread("SipService.Executor");
363 executorThread.start();
364 }
365 return executorThread.getLooper();
366 }
367
368 public SipServiceExecutor getExecutor() {
369 // create mExecutor lazily
370 if (mExecutor == null) {
371 mExecutor = new SipServiceExecutor(this);
372 }
373 return mExecutor;
374 }
375
376 // Executes immediate tasks in a single executorThread.
377 public static class SipServiceExecutor extends Handler {
378 WeakReference<SipService> handlerService;
379
380 SipServiceExecutor(SipService s) {
381 super(createLooper());
382 handlerService = new WeakReference<SipService>(s);
383 }
384
385 public void execute(Runnable task) {
386 // TODO: add wakelock
387 Message.obtain(this, 0/* don't care */, task).sendToTarget();
388 }
389
390 @Override
391 public void handleMessage(Message msg) {
392 if (msg.obj instanceof Runnable) {
393 executeInternal((Runnable) msg.obj);
394 } else {
395 Log.w(TAG, "can't handle msg: " + msg);
396 }
397 }
398
399 private void executeInternal(Runnable task) {
400 try {
401 task.run();
402 } catch (Throwable t) {
403 Log.e(TAG, "run task: " + task, t);
404 }
405 }
406 }
407
408 private void startPjSipStack() throws SameThreadException {
409 if (isPjSipStackStarted)
410 return;
411
412 try {
413 System.loadLibrary("gnustl_shared");
414 System.loadLibrary("expat");
415 System.loadLibrary("yaml");
416 System.loadLibrary("ccgnu2");
417 System.loadLibrary("crypto");
418 System.loadLibrary("ssl");
419 System.loadLibrary("ccrtp1");
420 System.loadLibrary("dbus");
421 System.loadLibrary("dbus-c++-1");
422 System.loadLibrary("samplerate");
423 System.loadLibrary("codec_ulaw");
424 System.loadLibrary("codec_alaw");
425 System.loadLibrary("speexresampler");
426 System.loadLibrary("sflphone");
427 isPjSipStackStarted = true;
428 } catch (UnsatisfiedLinkError e) {
429 Log.e(TAG, "Problem with the current Pj stack...", e);
430 isPjSipStackStarted = false;
431 return;
432 } catch (Exception e) {
433 Log.e(TAG, "Problem with the current Pj stack...", e);
434 }
435
Emeric Vigier0007dee2012-09-24 11:35:58 -0400436 /* get unique instance of managerImpl */
437 managerImpl = SFLPhoneservice.instance();
Alexandre Savard718d49f2012-10-02 15:17:13 -0400438
Emeric Vigier6119d782012-09-21 18:04:14 -0400439 /* set static AppPath before calling manager.init */
Emeric Vigier0007dee2012-09-24 11:35:58 -0400440 managerImpl.setPath(sflphoneApp.getAppPath());
Emeric Vigier6119d782012-09-21 18:04:14 -0400441
Alexandre Savard718d49f2012-10-02 15:17:13 -0400442 callManagerJNI = new CallManagerJNI();
Emeric Vigier0007dee2012-09-24 11:35:58 -0400443 callManagerCallBack = new CallManagerCallBack();
Alexandre Savard718d49f2012-10-02 15:17:13 -0400444
Emeric Vigier0007dee2012-09-24 11:35:58 -0400445 SFLPhoneservice.setCallbackObject(callManagerCallBack);
Emeric Vigier0007dee2012-09-24 11:35:58 -0400446
Alexandre Savardc1b08fe2012-09-25 16:24:47 -0400447 configurationManagerJNI = new ConfigurationManagerJNI();
448
Emeric Vigier0007dee2012-09-24 11:35:58 -0400449 managerImpl.init("");
Emeric Vigier6119d782012-09-21 18:04:14 -0400450 return;
451 }
452
453 // Enforce same thread contract to ensure we do not call from somewhere else
454 public class SameThreadException extends Exception {
455 private static final long serialVersionUID = -905639124232613768L;
456
457 public SameThreadException() {
458 super("Should be launched from a single worker thread");
459 }
460 }
461
462 public abstract static class SipRunnable implements Runnable {
463 protected abstract void doRun() throws SameThreadException;
464
465 public void run() {
466 try {
467 doRun();
468 }catch(SameThreadException e) {
469 Log.e(TAG, "Not done from same thread");
470 }
471 }
472 }
473
Alexandre Savard31d27c62012-10-04 16:05:08 -0400474 public abstract static class SipRunnableWithReturn implements Runnable {
475 Object obj = null;
476 boolean done = false;
477
478 protected abstract Object doRun() throws SameThreadException;
479
480 public Object getVal() {
481 return obj;
482 }
483
484 public boolean isDone() {
485 return done;
486 }
487
488 public void run() {
489 try {
490 obj = doRun();
491 done = true;
492 }catch(SameThreadException e) {
493 Log.e(TAG, "Not done from same thread");
494 }
495 }
496 }
497
Emeric Vigier6119d782012-09-21 18:04:14 -0400498 class StartRunnable extends SipRunnable {
499 @Override
500 protected void doRun() throws SameThreadException {
501 startPjSipStack();
Emeric Vigiereaf2c492012-09-19 14:38:20 -0400502 }
503 }
504
505 private class SipServiceThread extends Thread {
506
507 public SipServiceThread() {
508 super("sipServiceThread");
509 }
510
511 @Override
512 public void run() {
Emeric Vigier12d61d82012-09-19 15:08:18 -0400513 Log.i(TAG, "SipService thread running...");
Emeric Vigiereaf2c492012-09-19 14:38:20 -0400514 SipService sipService = SipService.this;
515 while(sipService.runFlag) {
516 try {
Emeric Vigiereaf2c492012-09-19 14:38:20 -0400517 Thread.sleep(DELAY);
518 } catch (InterruptedException e) {
519 sipService.runFlag = false;
520 Log.w(TAG, "service thread interrupted!");
521 }
522 }
523 }
524 }
525}