Changeset 5017 for pjproject/trunk/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MyApp.java
- Timestamp:
- Mar 22, 2015 10:22:44 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MyApp.java
r5016 r5017 26 26 27 27 /* Interface to separate UI & engine a bit better */ 28 interface MyAppObserver { 29 abstract void notifyRegState(pjsip_status_code code, String reason, int expiration); 30 abstract void notifyIncomingCall(MyCall call); 31 abstract void notifyCallState(MyCall call); 32 abstract void notifyCallMediaState(MyCall call); 33 abstract void notifyBuddyState(MyBuddy buddy); 34 } 35 36 37 class MyLogWriter extends LogWriter { 38 @Override 39 public void write(LogEntry entry) { 40 System.out.println(entry.getMsg()); 41 } 42 } 43 44 45 class MyCall extends Call { 46 public VideoWindow vidWin; 47 48 MyCall(MyAccount acc, int call_id) { 49 super(acc, call_id); 50 vidWin = null; 51 } 52 53 @Override 54 public void onCallState(OnCallStateParam prm) { 55 MyApp.observer.notifyCallState(this); 28 interface MyAppObserver 29 { 30 abstract void notifyRegState(pjsip_status_code code, String reason, 31 int expiration); 32 abstract void notifyIncomingCall(MyCall call); 33 abstract void notifyCallState(MyCall call); 34 abstract void notifyCallMediaState(MyCall call); 35 abstract void notifyBuddyState(MyBuddy buddy); 36 } 37 38 39 class MyLogWriter extends LogWriter 40 { 41 @Override 42 public void write(LogEntry entry) 43 { 44 System.out.println(entry.getMsg()); 45 } 46 } 47 48 49 class MyCall extends Call 50 { 51 public VideoWindow vidWin; 52 53 MyCall(MyAccount acc, int call_id) 54 { 55 super(acc, call_id); 56 vidWin = null; 57 } 58 59 @Override 60 public void onCallState(OnCallStateParam prm) 61 { 62 MyApp.observer.notifyCallState(this); 63 try { 64 CallInfo ci = getInfo(); 65 if (ci.getState() == 66 pjsip_inv_state.PJSIP_INV_STATE_DISCONNECTED) 67 { 68 this.delete(); 69 } 70 } catch (Exception e) { 71 return; 72 } 73 } 74 75 @Override 76 public void onCallMediaState(OnCallMediaStateParam prm) 77 { 78 CallInfo ci; 79 try { 80 ci = getInfo(); 81 } catch (Exception e) { 82 return; 83 } 84 85 CallMediaInfoVector cmiv = ci.getMedia(); 86 87 for (int i = 0; i < cmiv.size(); i++) { 88 CallMediaInfo cmi = cmiv.get(i); 89 if (cmi.getType() == pjmedia_type.PJMEDIA_TYPE_AUDIO && 90 (cmi.getStatus() == 91 pjsua_call_media_status.PJSUA_CALL_MEDIA_ACTIVE || 92 cmi.getStatus() == 93 pjsua_call_media_status.PJSUA_CALL_MEDIA_REMOTE_HOLD)) 94 { 95 // unfortunately, on Java too, the returned Media cannot be 96 // downcasted to AudioMedia 97 Media m = getMedia(i); 98 AudioMedia am = AudioMedia.typecastFromMedia(m); 99 100 // connect ports 56 101 try { 57 CallInfo ci = getInfo();58 if (ci.getState() == pjsip_inv_state.PJSIP_INV_STATE_DISCONNECTED) {59 this.delete();60 }102 MyApp.ep.audDevManager().getCaptureDevMedia(). 103 startTransmit(am); 104 am.startTransmit(MyApp.ep.audDevManager(). 105 getPlaybackDevMedia()); 61 106 } catch (Exception e) { 62 return;107 continue; 63 108 } 64 } 65 66 @Override 67 public void onCallMediaState(OnCallMediaStateParam prm) { 68 CallInfo ci; 109 } else if (cmi.getType() == pjmedia_type.PJMEDIA_TYPE_VIDEO && 110 cmi.getStatus() == 111 pjsua_call_media_status.PJSUA_CALL_MEDIA_ACTIVE && 112 cmi.getVideoIncomingWindowId() != pjsua2.INVALID_ID) 113 { 114 vidWin = new VideoWindow(cmi.getVideoIncomingWindowId()); 115 } 116 } 117 118 MyApp.observer.notifyCallMediaState(this); 119 } 120 } 121 122 123 class MyAccount extends Account 124 { 125 public ArrayList<MyBuddy> buddyList = new ArrayList<MyBuddy>(); 126 public AccountConfig cfg; 127 128 MyAccount(AccountConfig config) 129 { 130 super(); 131 cfg = config; 132 } 133 134 public MyBuddy addBuddy(BuddyConfig bud_cfg) 135 { 136 /* Create Buddy */ 137 MyBuddy bud = new MyBuddy(bud_cfg); 138 try { 139 bud.create(this, bud_cfg); 140 } catch (Exception e) { 141 bud.delete(); 142 bud = null; 143 } 144 145 if (bud != null) { 146 buddyList.add(bud); 147 if (bud_cfg.getSubscribe()) 69 148 try { 70 ci = getInfo(); 71 } catch (Exception e) { 72 return; 149 bud.subscribePresence(true); 150 } catch (Exception e) {} 151 } 152 153 return bud; 154 } 155 156 public void delBuddy(MyBuddy buddy) 157 { 158 buddyList.remove(buddy); 159 buddy.delete(); 160 } 161 162 public void delBuddy(int index) 163 { 164 MyBuddy bud = buddyList.get(index); 165 buddyList.remove(index); 166 bud.delete(); 167 } 168 169 @Override 170 public void onRegState(OnRegStateParam prm) 171 { 172 MyApp.observer.notifyRegState(prm.getCode(), prm.getReason(), 173 prm.getExpiration()); 174 } 175 176 @Override 177 public void onIncomingCall(OnIncomingCallParam prm) 178 { 179 System.out.println("======== Incoming call ======== "); 180 MyCall call = new MyCall(this, prm.getCallId()); 181 MyApp.observer.notifyIncomingCall(call); 182 } 183 184 @Override 185 public void onInstantMessage(OnInstantMessageParam prm) 186 { 187 System.out.println("======== Incoming pager ======== "); 188 System.out.println("From : " + prm.getFromUri()); 189 System.out.println("To : " + prm.getToUri()); 190 System.out.println("Contact : " + prm.getContactUri()); 191 System.out.println("Mimetype : " + prm.getContentType()); 192 System.out.println("Body : " + prm.getMsgBody()); 193 } 194 } 195 196 197 class MyBuddy extends Buddy 198 { 199 public BuddyConfig cfg; 200 201 MyBuddy(BuddyConfig config) 202 { 203 super(); 204 cfg = config; 205 } 206 207 String getStatusText() 208 { 209 BuddyInfo bi; 210 211 try { 212 bi = getInfo(); 213 } catch (Exception e) { 214 return "?"; 215 } 216 217 String status = ""; 218 if (bi.getSubState() == pjsip_evsub_state.PJSIP_EVSUB_STATE_ACTIVE) { 219 if (bi.getPresStatus().getStatus() == 220 pjsua_buddy_status.PJSUA_BUDDY_STATUS_ONLINE) 221 { 222 status = bi.getPresStatus().getStatusText(); 223 if (status == null || status.length()==0) { 224 status = "Online"; 73 225 } 74 75 CallMediaInfoVector cmiv = ci.getMedia(); 76 77 for (int i = 0; i < cmiv.size(); i++) { 78 CallMediaInfo cmi = cmiv.get(i); 79 if (cmi.getType() == pjmedia_type.PJMEDIA_TYPE_AUDIO && 80 (cmi.getStatus() == pjsua_call_media_status.PJSUA_CALL_MEDIA_ACTIVE || 81 cmi.getStatus() == pjsua_call_media_status.PJSUA_CALL_MEDIA_REMOTE_HOLD)) 82 { 83 // unfortunately, on Java too, the returned Media cannot be downcasted to AudioMedia 84 Media m = getMedia(i); 85 AudioMedia am = AudioMedia.typecastFromMedia(m); 86 87 // connect ports 88 try { 89 MyApp.ep.audDevManager().getCaptureDevMedia().startTransmit(am); 90 am.startTransmit(MyApp.ep.audDevManager().getPlaybackDevMedia()); 91 } catch (Exception e) { 92 continue; 93 } 94 } else if (cmi.getType() == pjmedia_type.PJMEDIA_TYPE_VIDEO && 95 cmi.getStatus() == pjsua_call_media_status.PJSUA_CALL_MEDIA_ACTIVE && 96 cmi.getVideoIncomingWindowId() != pjsua2.INVALID_ID) 97 { 98 vidWin = new VideoWindow(cmi.getVideoIncomingWindowId()); 99 } 100 } 101 102 MyApp.observer.notifyCallMediaState(this); 103 } 104 } 105 106 107 class MyAccount extends Account { 108 public ArrayList<MyBuddy> buddyList = new ArrayList<MyBuddy>(); 109 public AccountConfig cfg; 110 111 MyAccount(AccountConfig config) { 112 super(); 113 cfg = config; 114 } 115 116 public MyBuddy addBuddy(BuddyConfig bud_cfg) 117 { 118 /* Create Buddy */ 119 MyBuddy bud = new MyBuddy(bud_cfg); 120 try { 121 bud.create(this, bud_cfg); 122 } catch (Exception e) { 123 bud.delete(); 124 bud = null; 125 } 126 127 if (bud != null) { 128 buddyList.add(bud); 129 if (bud_cfg.getSubscribe()) 130 try { 131 bud.subscribePresence(true); 132 } catch (Exception e) {} 133 } 134 135 return bud; 136 } 137 138 public void delBuddy(MyBuddy buddy) { 139 buddyList.remove(buddy); 140 buddy.delete(); 141 } 142 143 public void delBuddy(int index) { 144 MyBuddy bud = buddyList.get(index); 145 buddyList.remove(index); 146 bud.delete(); 147 } 148 149 @Override 150 public void onRegState(OnRegStateParam prm) { 151 MyApp.observer.notifyRegState(prm.getCode(), prm.getReason(), prm.getExpiration()); 152 } 153 154 @Override 155 public void onIncomingCall(OnIncomingCallParam prm) { 156 System.out.println("======== Incoming call ======== "); 157 MyCall call = new MyCall(this, prm.getCallId()); 158 MyApp.observer.notifyIncomingCall(call); 159 } 160 161 @Override 162 public void onInstantMessage(OnInstantMessageParam prm) { 163 System.out.println("======== Incoming pager ======== "); 164 System.out.println("From : " + prm.getFromUri()); 165 System.out.println("To : " + prm.getToUri()); 166 System.out.println("Contact : " + prm.getContactUri()); 167 System.out.println("Mimetype : " + prm.getContentType()); 168 System.out.println("Body : " + prm.getMsgBody()); 169 } 170 } 171 172 173 class MyBuddy extends Buddy { 174 public BuddyConfig cfg; 175 176 MyBuddy(BuddyConfig config) { 177 super(); 178 cfg = config; 179 } 180 181 String getStatusText() { 182 BuddyInfo bi; 183 184 try { 185 bi = getInfo(); 186 } catch (Exception e) { 187 return "?"; 188 } 189 190 String status = ""; 191 if (bi.getSubState() == pjsip_evsub_state.PJSIP_EVSUB_STATE_ACTIVE) { 192 if (bi.getPresStatus().getStatus() == pjsua_buddy_status.PJSUA_BUDDY_STATUS_ONLINE) { 193 status = bi.getPresStatus().getStatusText(); 194 if (status == null || status.length()==0) { 195 status = "Online"; 196 } 197 } else if (bi.getPresStatus().getStatus() == pjsua_buddy_status.PJSUA_BUDDY_STATUS_OFFLINE) { 198 status = "Offline"; 199 } else { 200 status = "Unknown"; 201 } 202 } 203 return status; 204 } 205 206 @Override 207 public void onBuddyState() { 208 MyApp.observer.notifyBuddyState(this); 209 } 210 211 } 212 213 214 class MyAccountConfig { 215 public AccountConfig accCfg = new AccountConfig(); 216 public ArrayList<BuddyConfig> buddyCfgs = new ArrayList<BuddyConfig>(); 217 218 public void readObject(ContainerNode node) { 219 try { 220 ContainerNode acc_node = node.readContainer("Account"); 221 accCfg.readObject(acc_node); 222 ContainerNode buddies_node = acc_node.readArray("buddies"); 223 buddyCfgs.clear(); 224 while (buddies_node.hasUnread()) { 225 BuddyConfig bud_cfg = new BuddyConfig(); 226 bud_cfg.readObject(buddies_node); 227 buddyCfgs.add(bud_cfg); 228 } 229 } catch (Exception e) {} 230 } 231 232 public void writeObject(ContainerNode node) { 233 try { 234 ContainerNode acc_node = node.writeNewContainer("Account"); 235 accCfg.writeObject(acc_node); 236 ContainerNode buddies_node = acc_node.writeNewArray("buddies"); 237 for (int j = 0; j < buddyCfgs.size(); j++) { 238 buddyCfgs.get(j).writeObject(buddies_node); 239 } 240 } catch (Exception e) {} 241 } 226 } else if (bi.getPresStatus().getStatus() == 227 pjsua_buddy_status.PJSUA_BUDDY_STATUS_OFFLINE) 228 { 229 status = "Offline"; 230 } else { 231 status = "Unknown"; 232 } 233 } 234 return status; 235 } 236 237 @Override 238 public void onBuddyState() 239 { 240 MyApp.observer.notifyBuddyState(this); 241 } 242 243 } 244 245 246 class MyAccountConfig 247 { 248 public AccountConfig accCfg = new AccountConfig(); 249 public ArrayList<BuddyConfig> buddyCfgs = new ArrayList<BuddyConfig>(); 250 251 public void readObject(ContainerNode node) 252 { 253 try { 254 ContainerNode acc_node = node.readContainer("Account"); 255 accCfg.readObject(acc_node); 256 ContainerNode buddies_node = acc_node.readArray("buddies"); 257 buddyCfgs.clear(); 258 while (buddies_node.hasUnread()) { 259 BuddyConfig bud_cfg = new BuddyConfig(); 260 bud_cfg.readObject(buddies_node); 261 buddyCfgs.add(bud_cfg); 262 } 263 } catch (Exception e) {} 264 } 265 266 public void writeObject(ContainerNode node) 267 { 268 try { 269 ContainerNode acc_node = node.writeNewContainer("Account"); 270 accCfg.writeObject(acc_node); 271 ContainerNode buddies_node = acc_node.writeNewArray("buddies"); 272 for (int j = 0; j < buddyCfgs.size(); j++) { 273 buddyCfgs.get(j).writeObject(buddies_node); 274 } 275 } catch (Exception e) {} 276 } 242 277 } 243 278 244 279 245 280 class MyApp { 246 static { 247 try{ 248 System.loadLibrary("openh264"); 249 System.loadLibrary("yuv"); 250 } catch (UnsatisfiedLinkError e) { 251 System.out.println("UnsatisfiedLinkError: " + e.getMessage()); 252 System.out.println("This could be safely ignored if you " + 253 "don't need video."); 254 } 255 System.loadLibrary("pjsua2"); 256 System.out.println("Library loaded"); 257 } 258 259 public static Endpoint ep = new Endpoint(); 260 public static MyAppObserver observer; 261 public ArrayList<MyAccount> accList = new ArrayList<MyAccount>(); 262 263 private ArrayList<MyAccountConfig> accCfgs = new ArrayList<MyAccountConfig>(); 264 private EpConfig epConfig = new EpConfig(); 265 private TransportConfig sipTpConfig = new TransportConfig(); 266 private String appDir; 267 268 /* Maintain reference to log writer to avoid premature cleanup by GC */ 269 private MyLogWriter logWriter; 270 271 private final String configName = "pjsua2.json"; 272 private final int SIP_PORT = 6000; 273 private final int LOG_LEVEL = 4; 274 275 public void init(MyAppObserver obs, String app_dir) { 276 init(obs, app_dir, false); 277 } 278 279 public void init(MyAppObserver obs, String app_dir, boolean own_worker_thread) { 280 observer = obs; 281 appDir = app_dir; 282 283 /* Create endpoint */ 284 try { 285 ep.libCreate(); 286 } catch (Exception e) { 287 return; 288 } 289 290 291 /* Load config */ 292 String configPath = appDir + "/" + configName; 293 File f = new File(configPath); 294 if (f.exists()) { 295 loadConfig(configPath); 296 } else { 297 /* Set 'default' values */ 298 sipTpConfig.setPort(SIP_PORT); 299 } 300 301 /* Override log level setting */ 302 epConfig.getLogConfig().setLevel(LOG_LEVEL); 303 epConfig.getLogConfig().setConsoleLevel(LOG_LEVEL); 304 305 /* Set log config. */ 306 LogConfig log_cfg = epConfig.getLogConfig(); 307 logWriter = new MyLogWriter(); 308 log_cfg.setWriter(logWriter); 309 log_cfg.setDecor(log_cfg.getDecor() & 310 ~(pj_log_decoration.PJ_LOG_HAS_CR.swigValue() | 311 pj_log_decoration.PJ_LOG_HAS_NEWLINE.swigValue())); 312 313 /* Set ua config. */ 314 UaConfig ua_cfg = epConfig.getUaConfig(); 315 ua_cfg.setUserAgent("Pjsua2 Android " + ep.libVersion().getFull()); 316 StringVector stun_servers = new StringVector(); 317 stun_servers.add("stun.pjsip.org"); 318 ua_cfg.setStunServer(stun_servers); 319 if (own_worker_thread) { 320 ua_cfg.setThreadCnt(0); 321 ua_cfg.setMainThreadOnly(true); 322 } 323 324 /* Init endpoint */ 325 try { 326 ep.libInit(epConfig); 327 } catch (Exception e) { 328 return; 329 } 330 331 /* Create transports. */ 332 try { 333 ep.transportCreate(pjsip_transport_type_e.PJSIP_TRANSPORT_UDP, sipTpConfig); 334 } catch (Exception e) { 335 System.out.println(e); 336 } 337 338 try { 339 ep.transportCreate(pjsip_transport_type_e.PJSIP_TRANSPORT_TCP, sipTpConfig); 340 } catch (Exception e) { 341 System.out.println(e); 342 } 343 344 /* Create accounts. */ 345 for (int i = 0; i < accCfgs.size(); i++) { 346 MyAccountConfig my_cfg = accCfgs.get(i); 347 MyAccount acc = addAcc(my_cfg.accCfg); 348 if (acc == null) 349 continue; 350 351 /* Add Buddies */ 352 for (int j = 0; j < my_cfg.buddyCfgs.size(); j++) { 353 BuddyConfig bud_cfg = my_cfg.buddyCfgs.get(j); 354 acc.addBuddy(bud_cfg); 355 } 356 } 357 358 /* Start. */ 359 try { 360 ep.libStart(); 361 } catch (Exception e) { 362 return; 363 } 364 } 365 366 public MyAccount addAcc(AccountConfig cfg) { 367 MyAccount acc = new MyAccount(cfg); 368 try { 369 acc.create(cfg); 370 } catch (Exception e) { 371 acc = null; 372 return null; 373 } 374 375 accList.add(acc); 376 return acc; 377 } 378 379 public void delAcc(MyAccount acc) { 380 accList.remove(acc); 381 } 382 383 private void loadConfig(String filename) { 384 JsonDocument json = new JsonDocument(); 385 386 try { 387 /* Load file */ 388 json.loadFile(filename); 389 ContainerNode root = json.getRootContainer(); 390 391 /* Read endpoint config */ 392 epConfig.readObject(root); 393 394 /* Read transport config */ 395 ContainerNode tp_node = root.readContainer("SipTransport"); 396 sipTpConfig.readObject(tp_node); 397 398 /* Read account configs */ 399 accCfgs.clear(); 400 ContainerNode accs_node = root.readArray("accounts"); 401 while (accs_node.hasUnread()) { 402 MyAccountConfig acc_cfg = new MyAccountConfig(); 403 acc_cfg.readObject(accs_node); 404 accCfgs.add(acc_cfg); 405 } 406 } catch (Exception e) { 407 System.out.println(e); 408 } 409 410 /* Force delete json now, as I found that Java somehow destroys it 411 * after lib has been destroyed and from non-registered thread. 412 */ 413 json.delete(); 414 } 415 416 private void buildAccConfigs() { 417 /* Sync accCfgs from accList */ 418 accCfgs.clear(); 419 for (int i = 0; i < accList.size(); i++) { 420 MyAccount acc = accList.get(i); 421 MyAccountConfig my_acc_cfg = new MyAccountConfig(); 422 my_acc_cfg.accCfg = acc.cfg; 423 424 my_acc_cfg.buddyCfgs.clear(); 425 for (int j = 0; j < acc.buddyList.size(); j++) { 426 MyBuddy bud = acc.buddyList.get(j); 427 my_acc_cfg.buddyCfgs.add(bud.cfg); 428 } 429 430 accCfgs.add(my_acc_cfg); 431 } 432 } 433 434 private void saveConfig(String filename) { 435 JsonDocument json = new JsonDocument(); 436 437 try { 438 /* Write endpoint config */ 439 json.writeObject(epConfig); 440 441 /* Write transport config */ 442 ContainerNode tp_node = json.writeNewContainer("SipTransport"); 443 sipTpConfig.writeObject(tp_node); 444 445 /* Write account configs */ 446 buildAccConfigs(); 447 ContainerNode accs_node = json.writeNewArray("accounts"); 448 for (int i = 0; i < accCfgs.size(); i++) { 449 accCfgs.get(i).writeObject(accs_node); 450 } 451 452 /* Save file */ 453 json.saveFile(filename); 454 } catch (Exception e) {} 455 456 /* Force delete json now, as I found that Java somehow destroys it 457 * after lib has been destroyed and from non-registered thread. 458 */ 459 json.delete(); 460 } 461 462 public void deinit() { 463 String configPath = appDir + "/" + configName; 464 saveConfig(configPath); 465 466 /* Try force GC to avoid late destroy of PJ objects as they should be 467 * deleted before lib is destroyed. 468 */ 469 Runtime.getRuntime().gc(); 470 471 /* Shutdown pjsua. Note that Endpoint destructor will also invoke 472 * libDestroy(), so this will be a test of double libDestroy(). 473 */ 474 try { 475 ep.libDestroy(); 476 } catch (Exception e) {} 477 478 /* Force delete Endpoint here, to avoid deletion from a non- 479 * registered thread (by GC?). 480 */ 481 ep.delete(); 482 ep = null; 483 } 484 } 281 static { 282 try{ 283 System.loadLibrary("openh264"); 284 System.loadLibrary("yuv"); 285 } catch (UnsatisfiedLinkError e) { 286 System.out.println("UnsatisfiedLinkError: " + e.getMessage()); 287 System.out.println("This could be safely ignored if you " + 288 "don't need video."); 289 } 290 System.loadLibrary("pjsua2"); 291 System.out.println("Library loaded"); 292 } 293 294 public static Endpoint ep = new Endpoint(); 295 public static MyAppObserver observer; 296 public ArrayList<MyAccount> accList = new ArrayList<MyAccount>(); 297 298 private ArrayList<MyAccountConfig> accCfgs = 299 new ArrayList<MyAccountConfig>(); 300 private EpConfig epConfig = new EpConfig(); 301 private TransportConfig sipTpConfig = new TransportConfig(); 302 private String appDir; 303 304 /* Maintain reference to log writer to avoid premature cleanup by GC */ 305 private MyLogWriter logWriter; 306 307 private final String configName = "pjsua2.json"; 308 private final int SIP_PORT = 6000; 309 private final int LOG_LEVEL = 4; 310 311 public void init(MyAppObserver obs, String app_dir) 312 { 313 init(obs, app_dir, false); 314 } 315 316 public void init(MyAppObserver obs, String app_dir, 317 boolean own_worker_thread) 318 { 319 observer = obs; 320 appDir = app_dir; 321 322 /* Create endpoint */ 323 try { 324 ep.libCreate(); 325 } catch (Exception e) { 326 return; 327 } 328 329 330 /* Load config */ 331 String configPath = appDir + "/" + configName; 332 File f = new File(configPath); 333 if (f.exists()) { 334 loadConfig(configPath); 335 } else { 336 /* Set 'default' values */ 337 sipTpConfig.setPort(SIP_PORT); 338 } 339 340 /* Override log level setting */ 341 epConfig.getLogConfig().setLevel(LOG_LEVEL); 342 epConfig.getLogConfig().setConsoleLevel(LOG_LEVEL); 343 344 /* Set log config. */ 345 LogConfig log_cfg = epConfig.getLogConfig(); 346 logWriter = new MyLogWriter(); 347 log_cfg.setWriter(logWriter); 348 log_cfg.setDecor(log_cfg.getDecor() & 349 ~(pj_log_decoration.PJ_LOG_HAS_CR.swigValue() | 350 pj_log_decoration.PJ_LOG_HAS_NEWLINE.swigValue())); 351 352 /* Set ua config. */ 353 UaConfig ua_cfg = epConfig.getUaConfig(); 354 ua_cfg.setUserAgent("Pjsua2 Android " + ep.libVersion().getFull()); 355 StringVector stun_servers = new StringVector(); 356 stun_servers.add("stun.pjsip.org"); 357 ua_cfg.setStunServer(stun_servers); 358 if (own_worker_thread) { 359 ua_cfg.setThreadCnt(0); 360 ua_cfg.setMainThreadOnly(true); 361 } 362 363 /* Init endpoint */ 364 try { 365 ep.libInit(epConfig); 366 } catch (Exception e) { 367 return; 368 } 369 370 /* Create transports. */ 371 try { 372 ep.transportCreate(pjsip_transport_type_e.PJSIP_TRANSPORT_UDP, 373 sipTpConfig); 374 } catch (Exception e) { 375 System.out.println(e); 376 } 377 378 try { 379 ep.transportCreate(pjsip_transport_type_e.PJSIP_TRANSPORT_TCP, 380 sipTpConfig); 381 } catch (Exception e) { 382 System.out.println(e); 383 } 384 385 /* Create accounts. */ 386 for (int i = 0; i < accCfgs.size(); i++) { 387 MyAccountConfig my_cfg = accCfgs.get(i); 388 MyAccount acc = addAcc(my_cfg.accCfg); 389 if (acc == null) 390 continue; 391 392 /* Add Buddies */ 393 for (int j = 0; j < my_cfg.buddyCfgs.size(); j++) { 394 BuddyConfig bud_cfg = my_cfg.buddyCfgs.get(j); 395 acc.addBuddy(bud_cfg); 396 } 397 } 398 399 /* Start. */ 400 try { 401 ep.libStart(); 402 } catch (Exception e) { 403 return; 404 } 405 } 406 407 public MyAccount addAcc(AccountConfig cfg) 408 { 409 MyAccount acc = new MyAccount(cfg); 410 try { 411 acc.create(cfg); 412 } catch (Exception e) { 413 acc = null; 414 return null; 415 } 416 417 accList.add(acc); 418 return acc; 419 } 420 421 public void delAcc(MyAccount acc) 422 { 423 accList.remove(acc); 424 } 425 426 private void loadConfig(String filename) 427 { 428 JsonDocument json = new JsonDocument(); 429 430 try { 431 /* Load file */ 432 json.loadFile(filename); 433 ContainerNode root = json.getRootContainer(); 434 435 /* Read endpoint config */ 436 epConfig.readObject(root); 437 438 /* Read transport config */ 439 ContainerNode tp_node = root.readContainer("SipTransport"); 440 sipTpConfig.readObject(tp_node); 441 442 /* Read account configs */ 443 accCfgs.clear(); 444 ContainerNode accs_node = root.readArray("accounts"); 445 while (accs_node.hasUnread()) { 446 MyAccountConfig acc_cfg = new MyAccountConfig(); 447 acc_cfg.readObject(accs_node); 448 accCfgs.add(acc_cfg); 449 } 450 } catch (Exception e) { 451 System.out.println(e); 452 } 453 454 /* Force delete json now, as I found that Java somehow destroys it 455 * after lib has been destroyed and from non-registered thread. 456 */ 457 json.delete(); 458 } 459 460 private void buildAccConfigs() 461 { 462 /* Sync accCfgs from accList */ 463 accCfgs.clear(); 464 for (int i = 0; i < accList.size(); i++) { 465 MyAccount acc = accList.get(i); 466 MyAccountConfig my_acc_cfg = new MyAccountConfig(); 467 my_acc_cfg.accCfg = acc.cfg; 468 469 my_acc_cfg.buddyCfgs.clear(); 470 for (int j = 0; j < acc.buddyList.size(); j++) { 471 MyBuddy bud = acc.buddyList.get(j); 472 my_acc_cfg.buddyCfgs.add(bud.cfg); 473 } 474 475 accCfgs.add(my_acc_cfg); 476 } 477 } 478 479 private void saveConfig(String filename) 480 { 481 JsonDocument json = new JsonDocument(); 482 483 try { 484 /* Write endpoint config */ 485 json.writeObject(epConfig); 486 487 /* Write transport config */ 488 ContainerNode tp_node = json.writeNewContainer("SipTransport"); 489 sipTpConfig.writeObject(tp_node); 490 491 /* Write account configs */ 492 buildAccConfigs(); 493 ContainerNode accs_node = json.writeNewArray("accounts"); 494 for (int i = 0; i < accCfgs.size(); i++) { 495 accCfgs.get(i).writeObject(accs_node); 496 } 497 498 /* Save file */ 499 json.saveFile(filename); 500 } catch (Exception e) {} 501 502 /* Force delete json now, as I found that Java somehow destroys it 503 * after lib has been destroyed and from non-registered thread. 504 */ 505 json.delete(); 506 } 507 508 public void deinit() 509 { 510 String configPath = appDir + "/" + configName; 511 saveConfig(configPath); 512 513 /* Try force GC to avoid late destroy of PJ objects as they should be 514 * deleted before lib is destroyed. 515 */ 516 Runtime.getRuntime().gc(); 517 518 /* Shutdown pjsua. Note that Endpoint destructor will also invoke 519 * libDestroy(), so this will be a test of double libDestroy(). 520 */ 521 try { 522 ep.libDestroy(); 523 } catch (Exception e) {} 524 525 /* Force delete Endpoint here, to avoid deletion from a non- 526 * registered thread (by GC?). 527 */ 528 ep.delete(); 529 ep = null; 530 } 531 }
Note: See TracChangeset
for help on using the changeset viewer.