added account_[set_]sipnat API functions

added ua_update_account API function
go directly to settings of new account
fixed some main activity layout bugs
keep main activity interactive when screen is locked
removed aor from UserAgent class
added register method to UserAgent class
added foregrounded and isDeviceLocked util functions
updated libbaresip distribution
This commit is contained in:
Juha Heinanen
2018-06-03 18:08:31 +03:00
parent d7e624bc40
commit d3c7ce29ca
10 changed files with 204 additions and 102 deletions
+50 -20
View File
@@ -274,8 +274,8 @@ Java_com_tutpro_baresip_MainActivity_baresipStart(JNIEnv *env, jobject instance,
ua = le->data; ua = le->data;
sprintf(ua_buf, "%lu", (unsigned long)ua); sprintf(ua_buf, "%lu", (unsigned long)ua);
jstring javaUA = (*env)->NewStringUTF(env, ua_buf); jstring javaUA = (*env)->NewStringUTF(env, ua_buf);
LOGD("adding account %s/%s\n", ua_aor(ua), ua_buf); LOGD("adding UA for AoR %s/%s\n", ua_aor(ua), ua_buf);
jmethodID accountId = (*env)->GetMethodID(env, pctx->mainActivityClz, "addAccount", jmethodID accountId = (*env)->GetMethodID(env, pctx->mainActivityClz, "addUA",
"(Ljava/lang/String;)V"); "(Ljava/lang/String;)V");
(*env)->CallVoidMethod(env, pctx->mainActivityObj, accountId, javaUA); (*env)->CallVoidMethod(env, pctx->mainActivityObj, accountId, javaUA);
(*env)->DeleteLocalRef(env, javaUA); (*env)->DeleteLocalRef(env, javaUA);
@@ -569,29 +569,49 @@ Java_com_tutpro_baresip_AccountKt_account_1set_1mediaenc(JNIEnv *env, jobject th
(*env)->ReleaseStringUTFChars(env, javaMencid, mencid); (*env)->ReleaseStringUTFChars(env, javaMencid, mencid);
return res; return res;
} }
JNIEXPORT jstring JNICALL
Java_com_tutpro_baresip_AccountKt_account_1sipnat(JNIEnv *env, jobject thiz, jstring javaAcc)
{
const char *native_acc = (*env)->GetStringUTFChars(env, javaAcc, 0);
struct account *acc = (struct account *) strtoul(native_acc, NULL, 10);
(*env)->ReleaseStringUTFChars(env, javaAcc, native_acc);
if (acc) {
const char *sipnat = account_sipnat(acc);
if (sipnat) return (*env)->NewStringUTF(env, sipnat);
}
return (*env)->NewStringUTF(env, "");
}
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
Java_com_tutpro_baresip_UserAgent_00024Companion_ua_1alloc(JNIEnv *env, jobject thiz, Java_com_tutpro_baresip_AccountKt_account_1set_1sipnat(JNIEnv *env, jobject thiz,
jstring javaSipUri) { jstring javaAcc, jstring javaSipNat) {
const char *sip_uri = (*env)->GetStringUTFChars(env, javaSipUri, 0); const char *native_acc = (*env)->GetStringUTFChars(env, javaAcc, 0);
struct ua *ua; struct account *acc = (struct account *)strtoul(native_acc, NULL, 10);
LOGD("allocating UA '%s'\n", sip_uri); (*env)->ReleaseStringUTFChars(env, javaAcc, native_acc);
int res = ua_alloc(&ua, sip_uri); const char *sipnat = (*env)->GetStringUTFChars(env, javaSipNat, 0);
(*env)->ReleaseStringUTFChars(env, javaSipUri, sip_uri); int res;
if (res == 0) { if (strlen(sipnat) > 0)
char ua_buf[64]; res = account_set_sipnat(acc, sipnat);
UpdateContext *pctx = (UpdateContext*)(&g_ctx); else
sprintf(ua_buf, "%lu", (unsigned long)ua); res = account_set_sipnat(acc, NULL);
jstring javaUA = (*env)->NewStringUTF(env, ua_buf); (*env)->ReleaseStringUTFChars(env, javaSipNat, sipnat);
LOGD("adding account %s/%s\n", ua_aor(ua), ua_buf);
jmethodID accountId = (*env)->GetMethodID(env, pctx->mainActivityClz, "addAccount",
"(Ljava/lang/String;)V");
(*env)->CallVoidMethod(env, pctx->mainActivityObj, accountId, javaUA);
(*env)->DeleteLocalRef(env, javaUA);
}
return res; return res;
} }
JNIEXPORT jstring JNICALL
Java_com_tutpro_baresip_UserAgent_00024Companion_ua_1alloc(JNIEnv *env, jobject thiz,
jstring javaUri) {
const char *uri = (*env)->GetStringUTFChars(env, javaUri, 0);
struct ua *ua;
LOGD("allocating UA '%s'\n", uri);
int res = ua_alloc(&ua, uri);
(*env)->ReleaseStringUTFChars(env, javaUri, uri);
char ua_buf[64];
ua_buf[0] = '\0';
if (res == 0) sprintf(ua_buf, "%lu", (unsigned long)ua);
return (*env)->NewStringUTF(env, ua_buf);
}
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
Java_com_tutpro_baresip_UserAgent_00024Companion_ua_1register(JNIEnv *env, jobject thiz, Java_com_tutpro_baresip_UserAgent_00024Companion_ua_1register(JNIEnv *env, jobject thiz,
jstring javaUA) jstring javaUA)
@@ -622,6 +642,16 @@ Java_com_tutpro_baresip_UserAgent_00024Companion_ua_1isregistered(JNIEnv *env, j
return ua_isregistered(ua); return ua_isregistered(ua);
} }
JNIEXPORT jint JNICALL
Java_com_tutpro_baresip_UserAgent_00024Companion_ua_1update_1account(JNIEnv *env, jobject thiz,
jstring javaUA)
{
const char *native_ua = (*env)->GetStringUTFChars(env, javaUA, 0);
struct ua *ua = (struct ua *)strtoul(native_ua, NULL, 10);
(*env)->ReleaseStringUTFChars(env, javaUA, native_ua);
return ua_update_account(ua);
}
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_com_tutpro_baresip_UserAgent_00024Companion_ua_1destroy(JNIEnv *env, jobject thiz, Java_com_tutpro_baresip_UserAgent_00024Companion_ua_1destroy(JNIEnv *env, jobject thiz,
jstring javaUA) jstring javaUA)
@@ -93,7 +93,7 @@ class Account(val accp: String) {
fun findUA(aor: String): UserAgent? { fun findUA(aor: String): UserAgent? {
for (ua in MainActivity.uas) { for (ua in MainActivity.uas) {
if (ua.aor == aor) return ua if (ua.account.aor == aor) return ua
} }
return null return null
} }
@@ -117,6 +117,8 @@ external fun account_auth_pass(acc: String): String
external fun account_set_auth_pass(acc: String, pass: String): Int external fun account_set_auth_pass(acc: String, pass: String): Int
external fun account_outbound(acc: String, ix: Int): String external fun account_outbound(acc: String, ix: Int): String
external fun account_set_outbound(acc: String, ob: String, ix: Int): Int external fun account_set_outbound(acc: String, ob: String, ix: Int): Int
external fun account_sipnat(acc: String): String
external fun account_set_sipnat(acc: String, sipnat: String): Int
external fun account_audio_codec(acc: String, ix: Int): String external fun account_audio_codec(acc: String, ix: Int): String
external fun account_regint(acc: String): Int external fun account_regint(acc: String): Int
external fun account_set_regint(acc: String, regint: Int): Int external fun account_set_regint(acc: String, regint: Int): Int
@@ -1,5 +1,6 @@
package com.tutpro.baresip package com.tutpro.baresip
import android.app.Activity
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.support.v7.app.AppCompatActivity import android.support.v7.app.AppCompatActivity
@@ -58,7 +59,7 @@ class AccountActivity : AppCompatActivity() {
while (newCodecs.size < audioCodecs.size) newCodecs.add("") while (newCodecs.size < audioCodecs.size) newCodecs.add("")
val layout = findViewById(R.id.CodecSpinners) as LinearLayout val layout = findViewById(R.id.CodecSpinners) as LinearLayout
var spinnerList = Array(audioCodecs.size, {i -> ArrayList<String>()}) val spinnerList = Array(audioCodecs.size, {_ -> ArrayList<String>()})
for (i in audioCodecs.indices) { for (i in audioCodecs.indices) {
val spinner = Spinner(applicationContext) val spinner = Spinner(applicationContext)
spinner.id = i + 100 spinner.id = i + 100
@@ -121,7 +122,7 @@ class AccountActivity : AppCompatActivity() {
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
val i = Intent(this, MainActivity::class.java) val intent = Intent(this, MainActivity::class.java)
if (item.itemId == R.id.checkIcon) { if (item.itemId == R.id.checkIcon) {
@@ -163,7 +164,7 @@ class AccountActivity : AppCompatActivity() {
if (Utils.checkPrintASCII(ap)) { if (Utils.checkPrintASCII(ap)) {
if (account_set_auth_pass(acc.accp, ap) == 0) { if (account_set_auth_pass(acc.accp, ap) == 0) {
acc.authPass = account_auth_pass(acc.accp) acc.authPass = account_auth_pass(acc.accp)
Log.d("Baresip", "New auth password is ${acc.authPass}") // Log.d("Baresip", "New auth password is ${acc.authPass}")
save = true save = true
} else { } else {
Log.e("Baresip", "Setting of auth pass failed") Log.e("Baresip", "Setting of auth pass failed")
@@ -199,6 +200,10 @@ class AccountActivity : AppCompatActivity() {
} }
Log.d("Baresip", "New outbound proxies are ${outbound}") Log.d("Baresip", "New outbound proxies are ${outbound}")
acc.outbound = outbound acc.outbound = outbound
if (outbound.isEmpty())
account_set_sipnat(acc.accp, "")
else
account_set_sipnat(acc.accp, "outbound")
save = true save = true
} }
@@ -253,24 +258,25 @@ class AccountActivity : AppCompatActivity() {
if (save) { if (save) {
AccountsActivity.saveAccounts() AccountsActivity.saveAccounts()
if (acc.regint > 0) { val uaIndex = UserAgent.findAorIndex(MainActivity.uas, aor)
Log.d("Baresip", "Registering ${acc.aor}") if (uaIndex != null) {
UserAgent.ua_register(Account.findUA(acc.aor)!!.uap) if (UserAgent.ua_update_account(MainActivity.uas[uaIndex].uap) != 0)
Log.e("Baresip", "Failed to update UA with AoR $aor")
else if (acc.regint > 0)
UserAgent.ua_register(MainActivity.uas[uaIndex].uap)
} else {
Log.e("Baresip", "Did not find UA matching AoR $aor")
} }
} }
setResult(RESULT_OK, i)
setResult(RESULT_OK, intent)
finish() finish()
return true return true
} else if (item.itemId == android.R.id.home) { } else if (item.itemId == android.R.id.home) {
Log.d("Baresip", "Back array was pressed at Account") Log.d("Baresip", "Back array was pressed at Account")
i.putExtra("action", "cancel") setResult(RESULT_CANCELED, intent)
if (acc.regint > 0) {
Log.d("Baresip", "Registering ${acc.aor}")
UserAgent.ua_register(Account.findUA(acc.aor)!!.uap)
}
setResult(RESULT_OK, i)
finish() finish()
return true return true
@@ -37,12 +37,9 @@ class AccountListAdapter(private val cxt: Context, private val rows: ArrayList<A
actionView.setOnClickListener { _ -> actionView.setOnClickListener { _ ->
Log.d("Baresip", "Delete button clicked") Log.d("Baresip", "Delete button clicked")
val deleteDialog = AlertDialog.Builder(cxt) val deleteDialog = AlertDialog.Builder(cxt)
deleteDialog.setMessage("Do you want to delete account ${MainActivity.uas[position].aor}?") deleteDialog.setMessage("Do you want to delete account ${MainActivity.uas[position].account.aor}?")
deleteDialog.setPositiveButton("Delete") { dialog, _ -> deleteDialog.setPositiveButton("Delete") { dialog, _ ->
if (UserAgent.ua_isregistered(MainActivity.uas[position].uap)) { MainActivity.uas[position].destroy()
UserAgent.ua_unregister(MainActivity.uas[position].uap)
}
UserAgent.ua_destroy(MainActivity.uas[position].uap)
MainActivity.uas.remove(MainActivity.uas[position]) MainActivity.uas.remove(MainActivity.uas[position])
MainActivity.images.removeAt(position) MainActivity.images.removeAt(position)
AccountsActivity.saveAccounts() AccountsActivity.saveAccounts()
@@ -15,6 +15,7 @@ import java.util.ArrayList
class AccountsActivity : AppCompatActivity() { class AccountsActivity : AppCompatActivity() {
internal var aor: String = "" internal var aor: String = ""
internal lateinit var alAdapter: AccountListAdapter
public override fun onCreate(savedInstanceState: Bundle?) { public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@@ -22,7 +23,7 @@ class AccountsActivity : AppCompatActivity() {
val listview = findViewById(R.id.accounts) as ListView val listview = findViewById(R.id.accounts) as ListView
generateAccounts() generateAccounts()
val alAdapter = AccountListAdapter(this, accounts) alAdapter = AccountListAdapter(this, accounts)
listview.adapter = alAdapter listview.adapter = alAdapter
val addAccountButton = findViewById(R.id.addAccount) as ImageButton val addAccountButton = findViewById(R.id.addAccount) as ImageButton
@@ -37,17 +38,26 @@ class AccountsActivity : AppCompatActivity() {
} else if (Account.exists(MainActivity.uas, aor)) { } else if (Account.exists(MainActivity.uas, aor)) {
Log.e("Baresip", "Account $aor already exists") Log.e("Baresip", "Account $aor already exists")
} else { } else {
if (UserAgent.ua_alloc("<$aor>;regq=0.5;pubint=0;regint=600") != 0) { val ua = UserAgent.uaAlloc("<$aor>;regq=0.5;pubint=0;regint=0")
Log.e("Baresip", "Failed to allocate UA $aor") if (ua == null) {
Log.e("Baresip", "Failed to allocate UA for $aor")
Utils.alertView(this, "Notice", Utils.alertView(this, "Notice",
"Failed to allocate new account. Check your network connection.") "Failed to allocate new account.")
} else { } else {
SystemClock.sleep(200);
newAorView.setText("") newAorView.setText("")
newAorView.setHint("SIP URI user@domain") newAorView.hint = "SIP URI user@domain"
newAorView.clearFocus() newAorView.clearFocus()
MainActivity.uas.add(ua)
MainActivity.images.add(R.drawable.dot_yellow)
generateAccounts()
alAdapter.notifyDataSetChanged()
saveAccounts() saveAccounts()
recreate() val i = Intent(this, AccountActivity::class.java)
val b = Bundle()
b.putString("accp", ua.account.accp)
i.putExtras(b)
startActivity(i)
// recreate()
} }
} }
} }
@@ -84,7 +94,8 @@ class AccountsActivity : AppCompatActivity() {
posAtAccounts.clear() posAtAccounts.clear()
var i = 0; var i = 0;
for (ua in MainActivity.uas) { for (ua in MainActivity.uas) {
accounts.add(AccountRow(ua.aor.replace("sip:", ""), R.drawable.action_remove)) accounts.add(AccountRow(ua.account.aor.replace("sip:", ""),
R.drawable.action_remove))
posAtAccounts.add(i) posAtAccounts.add(i)
i++ i++
} }
@@ -95,7 +106,7 @@ class AccountsActivity : AppCompatActivity() {
for (a in Account.accounts()) accounts = accounts + a.print() + "\n" for (a in Account.accounts()) accounts = accounts + a.print() + "\n"
val path = MainActivity.filesPath + "/accounts" val path = MainActivity.filesPath + "/accounts"
Utils.putFileContents(File(path), accounts) Utils.putFileContents(File(path), accounts)
// Log.d("Baresip", "Saved accounts '${accounts}' to '$path") // Log.d("Baresip", "Saved accounts '${accounts}' to '$path")
} }
} }
@@ -36,13 +36,8 @@ class Call(val callp: String, val ua: UserAgent, val peerURI: String, val dir: S
return null return null
} }
fun index(calls: ArrayList<Call>, call: Call, dir: String): Int { fun uaCallIndex(calls: ArrayList<Call>, ua: UserAgent, call: Call, dir: String): Int {
var res = 0 return uaCalls(calls, ua, dir).indexOf(call)
for (c in calls) {
if (c == call) return res
if ((dir == "") || (call.dir == dir)) res++
}
return res
} }
} }
@@ -56,6 +56,11 @@ class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
appContext = applicationContext appContext = applicationContext
@@ -75,22 +80,17 @@ class MainActivity : AppCompatActivity() {
wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK or wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK or
PowerManager.ACQUIRE_CAUSES_WAKEUP, "") PowerManager.ACQUIRE_CAUSES_WAKEUP, "")
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)
nb = NotificationCompat.Builder(this) nb = NotificationCompat.Builder(this)
nb.setVisibility(VISIBILITY_PUBLIC).setOngoing(true).setSmallIcon(R.drawable.ic_stat) nb.setVisibility(VISIBILITY_PUBLIC).setOngoing(true).setSmallIcon(R.drawable.ic_stat)
.setContentIntent( .setContentIntent(
PendingIntent.getActivity(this, NOTIFICATION_ID, PendingIntent.getActivity(this, NOTIFICATION_ID,
Intent(this, MainActivity::class.java) Intent(this, MainActivity::class.java)
.setAction(Intent.ACTION_MAIN) .setAction(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_LAUNCHER) .addCategory(Intent.CATEGORY_LAUNCHER),
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
PendingIntent.FLAG_UPDATE_CURRENT)) PendingIntent.FLAG_UPDATE_CURRENT))
.setContent(RemoteViews(getPackageName(), R.layout.notification)) .setContent(RemoteViews(getPackageName(), R.layout.notification))
val intentFilter = IntentFilter("android.net.conn.CONNECTIVITY_CHANGE") val netFilter = IntentFilter("android.net.conn.CONNECTIVITY_CHANGE")
receiver = object : BroadcastReceiver() { receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
val intentExtras = intent.extras val intentExtras = intent.extras
@@ -99,7 +99,7 @@ class MainActivity : AppCompatActivity() {
if (running) UserAgent.register(uas) if (running) UserAgent.register(uas)
} }
} }
registerReceiver(receiver, intentFilter) registerReceiver(receiver, netFilter)
aorSpinner = findViewById(R.id.AoRList) as Spinner aorSpinner = findViewById(R.id.AoRList) as Spinner
uaAdapter = UaSpinnerAdapter(applicationContext, uas, images) uaAdapter = UaSpinnerAdapter(applicationContext, uas, images)
@@ -150,15 +150,11 @@ class MainActivity : AppCompatActivity() {
val `in` = Call.uaCalls(calls, ua, "in") val `in` = Call.uaCalls(calls, ua, "in")
val view_count = layout.childCount val view_count = layout.childCount
Log.d("Baresip", "View count is $view_count") Log.d("Baresip", "View count is $view_count")
if (view_count > 7) { if (view_count > 7)
// remove all incoming call views
layout.removeViews(7, view_count - 7) layout.removeViews(7, view_count - 7)
} for (c in `in`)
for (c in `in`) { for (call_index in Call.uaCalls(calls, ua,"in").indices)
for (call_index in Call.calls(calls, "in").indices) {
addCallViews(ua, c, (call_index + 1) * 10) addCallViews(ua, c, (call_index + 1) * 10)
}
}
} }
override fun onNothingSelected(parent: AdapterView<*>) { override fun onNothingSelected(parent: AdapterView<*>) {
@@ -278,7 +274,7 @@ class MainActivity : AppCompatActivity() {
callButton.tag = "Call" callButton.tag = "Call"
callButton.setOnClickListener { callButton.setOnClickListener {
val ua = uas[aorSpinner.selectedItemPosition] val ua = uas[aorSpinner.selectedItemPosition]
val aor = ua.aor val aor = ua.account.aor
when (callButton.tag) { when (callButton.tag) {
"Call" -> { "Call" -> {
val calleeText = (findViewById(R.id.callee) as EditText).text.toString() val calleeText = (findViewById(R.id.callee) as EditText).text.toString()
@@ -341,7 +337,7 @@ class MainActivity : AppCompatActivity() {
historyButton.setOnClickListener { historyButton.setOnClickListener {
val i = Intent(this@MainActivity, HistoryActivity::class.java) val i = Intent(this@MainActivity, HistoryActivity::class.java)
val b = Bundle() val b = Bundle()
b.putString("aor", uas[aorSpinner.selectedItemPosition].aor) b.putString("aor", uas[aorSpinner.selectedItemPosition].account.aor)
i.putExtras(b) i.putExtras(b)
startActivityForResult(i, HISTORY_CODE) startActivityForResult(i, HISTORY_CODE)
} }
@@ -362,6 +358,17 @@ class MainActivity : AppCompatActivity() {
} }
} }
override fun onPause() {
super.onPause()
Log.d("Baresip", "Paused")
}
override fun onResume() {
super.onResume()
Log.d("Baresip", "Resumed")
nm.cancel(INCOMING_ID)
}
override fun onConfigurationChanged(newConfig: Configuration) { override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig) super.onConfigurationChanged(newConfig)
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
@@ -405,11 +412,10 @@ class MainActivity : AppCompatActivity() {
am.isSpeakerphoneOn = !am.isSpeakerphoneOn am.isSpeakerphoneOn = !am.isSpeakerphoneOn
val speakerIcon = findViewById(R.id.speakerIcon) as ActionMenuItemView val speakerIcon = findViewById(R.id.speakerIcon) as ActionMenuItemView
if (am.isSpeakerphoneOn) if (am.isSpeakerphoneOn)
// speakerIcon.setIcon(ContextCompat.getDrawable(this, R.drawable.speaker_on))
speakerIcon.setBackgroundColor(Color.rgb(0x04, 0xb4, 0x04)) speakerIcon.setBackgroundColor(Color.rgb(0x04, 0xb4, 0x04))
else else
// speakerIcon.setBackgroundColor(resources.getColor(R.color.colorPrimary, applicationContext.theme)) speakerIcon.setBackgroundColor(ContextCompat.getColor(applicationContext,
speakerIcon.setBackgroundColor(resources.getColor(R.color.colorPrimary)) R.color.colorPrimary))
return true return true
} }
R.id.accounts -> { R.id.accounts -> {
@@ -489,7 +495,7 @@ class MainActivity : AppCompatActivity() {
} }
if (resultCode == RESULT_CANCELED) { if (resultCode == RESULT_CANCELED) {
Log.d("Baresip", "History canceled") Log.d("Baresip", "History canceled")
if (History.aorHistory(history, uas[aorSpinner.selectedItemPosition].aor) == 0) { if (History.aorHistory(history, uas[aorSpinner.selectedItemPosition].account.aor) == 0) {
holdButton.visibility = View.INVISIBLE holdButton.visibility = View.INVISIBLE
} }
} }
@@ -727,16 +733,16 @@ class MainActivity : AppCompatActivity() {
} }
@Keep @Keep
fun addAccount(ua: String) { fun addUA(uap: String) {
val userAgent = UserAgent(ua) val ua = UserAgent(uap)
uas.add(userAgent) uas.add(ua)
if (UserAgent.ua_isregistered(ua)) { if (UserAgent.ua_isregistered(uap)) {
Log.d("Baresip", "Ua $ua is registered") Log.d("Baresip", "Ua $ua is registered")
images.add(R.drawable.dot_green) images.add(R.drawable.dot_green)
} else { } else {
Log.d("Baresip", "Ua $ua is NOT registered") Log.d("Baresip", "Ua $ua is NOT registered")
images.add(R.drawable.dot_yellow) images.add(R.drawable.dot_yellow)
UserAgent.ua_register(ua) ua.register()
} }
this@MainActivity.runOnUiThread { this@MainActivity.runOnUiThread {
uaAdapter.notifyDataSetChanged() uaAdapter.notifyDataSetChanged()
@@ -753,14 +759,14 @@ class MainActivity : AppCompatActivity() {
Log.e("Baresip", "Update status did not find ua $uap") Log.e("Baresip", "Update status did not find ua $uap")
return return
} }
val aor = ua.aor val aor = ua.account.aor
val acc = ua.account val acc = ua.account
val ev = event.split(",") val ev = event.split(",")
Log.d("Baresip", "Handling event ${ev[0]} for $uap/$callp/$aor") Log.d("Baresip", "Handling event ${ev[0]} for $uap/$callp/$aor")
for (account_index in uas.indices) { for (account_index in uas.indices) {
if (uas[account_index].aor == aor) { if (uas[account_index].account.aor == aor) {
Log.d("Baresip", "Found AoR at index $account_index") Log.d("Baresip", "Found AoR at index $account_index")
when (ev[0]) { when (ev[0]) {
"registering", "unregistering" -> { "registering", "unregistering" -> {
@@ -796,13 +802,16 @@ class MainActivity : AppCompatActivity() {
this@MainActivity.runOnUiThread { this@MainActivity.runOnUiThread {
calls.add(new_call) calls.add(new_call)
if (ua != uas[aorSpinner.selectedItemPosition]) if (ua != uas[aorSpinner.selectedItemPosition])
aorSpinner.setSelection(UserAgent.findAorIndex(uas, aor)!!) aorSpinner.setSelection(account_index)
addCallViews(ua, new_call, Call.calls(calls, "in").size * 10) else
addCallViews(ua, new_call, Call.uaCalls(calls, ua,"in").size * 10)
am.mode = AudioManager.MODE_RINGTONE am.mode = AudioManager.MODE_RINGTONE
} }
val i = Intent(this, MainActivity::class.java) if (Utils.foregrounded()) {
i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) val i = Intent(this, MainActivity::class.java)
startActivity(i) i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
startActivity(i)
}
} }
"call established" -> { "call established" -> {
val call = Call.find(calls, callp) val call = Call.find(calls, callp)
@@ -845,7 +854,7 @@ class MainActivity : AppCompatActivity() {
this@MainActivity.runOnUiThread { this@MainActivity.runOnUiThread {
if (ua == uas[aorSpinner.selectedItemPosition]) { if (ua == uas[aorSpinner.selectedItemPosition]) {
if (acc.mediaenc != "") { if (acc.mediaenc != "") {
val inIndex = Call.index(calls, call, "in") val inIndex = Call.uaCallIndex(calls, ua, call, "in")
val view_id = (inIndex + 1) * 10 + 3 val view_id = (inIndex + 1) * 10 + 3
val securityButton = findViewById(view_id) as ImageButton val securityButton = findViewById(view_id) as ImageButton
securityButton.setImageResource(R.drawable.box_red) securityButton.setImageResource(R.drawable.box_red)
@@ -895,7 +904,7 @@ class MainActivity : AppCompatActivity() {
securityButton.visibility = View.VISIBLE securityButton.visibility = View.VISIBLE
} else { } else {
if (ua == uas[aorSpinner.selectedItemPosition]) { if (ua == uas[aorSpinner.selectedItemPosition]) {
val view_id = (Call.index(calls, call, "in") + 1) * 10 + 3 val view_id = (Call.uaCallIndex(calls, ua, call,"in") + 1) * 10 + 3
val securityButton = layout.findViewById(view_id) as ImageButton val securityButton = layout.findViewById(view_id) as ImageButton
securityButton.setImageResource(security) securityButton.setImageResource(security)
setSecurityButtonTag(securityButton, security) setSecurityButtonTag(securityButton, security)
@@ -913,7 +922,7 @@ class MainActivity : AppCompatActivity() {
securityButton.visibility = View.VISIBLE securityButton.visibility = View.VISIBLE
} else { } else {
if (ua == uas[aorSpinner.selectedItemPosition]) { if (ua == uas[aorSpinner.selectedItemPosition]) {
val view_id = (Call.index(calls, call, "in") + 1) * 10 + 3 val view_id = (Call.uaCallIndex(calls, ua, call,"in") + 1) * 10 + 3
val securityButton = layout.findViewById(view_id) as ImageButton val securityButton = layout.findViewById(view_id) as ImageButton
securityButton.setImageResource(R.drawable.box_yellow) securityButton.setImageResource(R.drawable.box_yellow)
securityButton.tag = "yellow" securityButton.tag = "yellow"
@@ -944,7 +953,7 @@ class MainActivity : AppCompatActivity() {
} else { } else {
this@MainActivity.runOnUiThread { this@MainActivity.runOnUiThread {
if (ua == uas[aorSpinner.selectedItemPosition]) { if (ua == uas[aorSpinner.selectedItemPosition]) {
val view_id = (Call.index(calls, call, "in") + 1) * 10 + 3 val view_id = (Call.uaCallIndex(calls, ua, call, "in") + 1) * 10 + 3
val securityButton = layout.findViewById(view_id) as ImageButton val securityButton = layout.findViewById(view_id) as ImageButton
securityButton.setImageResource(R.drawable.box_green) securityButton.setImageResource(R.drawable.box_green)
securityButton.tag = "green" securityButton.tag = "green"
@@ -962,10 +971,10 @@ class MainActivity : AppCompatActivity() {
if (call.dir == "in") { if (call.dir == "in") {
Log.d("Baresip", "Removing inbound call ${uap}/${callp}/" + Log.d("Baresip", "Removing inbound call ${uap}/${callp}/" +
call.peerURI) call.peerURI)
val inIndex = Call.index(calls, call, "in") val inIndex = Call.uaCallIndex(calls, ua, call, "in")
val view_id = (inIndex + 1) * 10 val view_id = (inIndex + 1) * 10
val remove_count = Call.calls(calls, "in").size - inIndex val remove_count = Call.uaCalls(calls, ua,"in").size - inIndex
calls.removeAt(Call.index(calls, call, "")) calls.remove(call)
this@MainActivity.runOnUiThread { this@MainActivity.runOnUiThread {
if (ua == uas[aorSpinner.selectedItemPosition]) { if (ua == uas[aorSpinner.selectedItemPosition]) {
if (callButton.tag == "Call") { if (callButton.tag == "Call") {
@@ -974,7 +983,7 @@ class MainActivity : AppCompatActivity() {
val caller_heading = layout.findViewById(view_id) val caller_heading = layout.findViewById(view_id)
val view_index = layout.indexOfChild(caller_heading) val view_index = layout.indexOfChild(caller_heading)
layout.removeViews(view_index, 3 * remove_count) layout.removeViews(view_index, 3 * remove_count)
val callsIn = Call.calls(calls, "in") val callsIn = Call.uaCalls(calls, ua,"in")
for (i in inIndex until callsIn.size) { for (i in inIndex until callsIn.size) {
this@MainActivity.addCallViews(ua, callsIn[i], (i + 1) * 10) this@MainActivity.addCallViews(ua, callsIn[i], (i + 1) * 10)
} }
@@ -1005,7 +1014,7 @@ class MainActivity : AppCompatActivity() {
dtmf.visibility = View.INVISIBLE dtmf.visibility = View.INVISIBLE
historyButton.visibility = View.VISIBLE historyButton.visibility = View.VISIBLE
} }
calls.removeAt(Call.index(calls, call, "")) calls.remove(call)
} }
if (!call.hasHistory) { if (!call.hasHistory) {
if (History.aorHistory(history, aor) > HISTORY_SIZE) if (History.aorHistory(history, aor) > HISTORY_SIZE)
@@ -1079,6 +1088,7 @@ class MainActivity : AppCompatActivity() {
const val RECORD_AUDIO_PERMISSION = 1 const val RECORD_AUDIO_PERMISSION = 1
const val HISTORY_SIZE = 100 const val HISTORY_SIZE = 100
const val NOTIFICATION_ID = 10 const val NOTIFICATION_ID = 10
const val INCOMING_ID = 11
external fun contacts_remove() external fun contacts_remove()
external fun contact_add(contact: String) external fun contact_add(contact: String)
@@ -27,7 +27,7 @@ class UaSpinnerAdapter(private val cxt: Context, private val uas: ArrayList<User
val inflater = cxt.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater val inflater = cxt.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val row = inflater.inflate(R.layout.account_spinner, parent, false) val row = inflater.inflate(R.layout.account_spinner, parent, false)
val textView = row.findViewById(R.id.spinnerText) as TextView val textView = row.findViewById(R.id.spinnerText) as TextView
textView.text = uas[position].aor.replace("sip:", "") textView.text = uas[position].account.aor.replace("sip:", "")
textView.textSize = 17f textView.textSize = 17f
val imageView = row.findViewById(R.id.spinnerImage) as ImageView val imageView = row.findViewById(R.id.spinnerImage) as ImageView
imageView.setImageResource(images[position]) imageView.setImageResource(images[position])
@@ -5,16 +5,37 @@ import android.util.Log
class UserAgent (val uap: String) { class UserAgent (val uap: String) {
val account = Account(ua_account(uap)) val account = Account(ua_account(uap))
val aor = ua_aor(uap)
fun register() {
if (account.regint > 0) {
Log.d("Baresip", "Registering ${account.aor} UA ${uap}")
val accp = ua_account(uap)
val reg_int = account_regint(accp)
Log.d("Baresip", "reg_int is $reg_int")
if (ua_register(uap) != 0)
Log.e("Baresip", "Registering failed")
}
}
fun destroy() {
ua_destroy(uap)
}
companion object { companion object {
external fun ua_alloc(uri: String): Int external fun ua_alloc(uri: String): String
external fun ua_update_account(ua: String): Int
external fun ua_destroy(ua: String) external fun ua_destroy(ua: String)
external fun ua_register(ua: String): Int external fun ua_register(ua: String): Int
external fun ua_isregistered(ua: String): Boolean external fun ua_isregistered(ua: String): Boolean
external fun ua_unregister(ua: String) external fun ua_unregister(ua: String)
fun uaAlloc(uri: String): UserAgent? {
val uap = ua_alloc(uri)
if (uap != "") return UserAgent(uap)
return null
}
fun find(uas: ArrayList<UserAgent>, uap: String): UserAgent? { fun find(uas: ArrayList<UserAgent>, uap: String): UserAgent? {
for (ua in uas) { for (ua in uas) {
if (ua.uap == uap) return ua if (ua.uap == uap) return ua
@@ -24,7 +45,7 @@ class UserAgent (val uap: String) {
fun findAorIndex(uas: ArrayList<UserAgent>, aor: String): Int? { fun findAorIndex(uas: ArrayList<UserAgent>, aor: String): Int? {
for (i in uas.indices) { for (i in uas.indices) {
if (uas[i].aor == aor) return i if (uas[i].account.aor == aor) return i
} }
return null return null
} }
@@ -32,7 +53,7 @@ class UserAgent (val uap: String) {
fun register(uas: ArrayList<UserAgent>) { fun register(uas: ArrayList<UserAgent>) {
for (ua in uas) { for (ua in uas) {
if (ua_register(ua.uap) != 0) if (ua_register(ua.uap) != 0)
Log.e("Baresip", "Failed to register ${ua.aor}") Log.e("Baresip", "Failed to register ${ua.account.aor}")
} }
} }
} }
@@ -1,11 +1,17 @@
package com.tutpro.baresip package com.tutpro.baresip
import android.app.ActivityManager
import android.content.Context import android.content.Context
import android.support.v7.app.AlertDialog import android.support.v7.app.AlertDialog
import android.util.Log import android.util.Log
import android.net.ConnectivityManager import android.net.ConnectivityManager
import java.io.* import java.io.*
import android.os.Build
import android.os.PowerManager
import android.app.KeyguardManager
object Utils { object Utils {
@@ -127,6 +133,30 @@ object Utils {
} }
} }
fun foregrounded(): Boolean {
val appProcessInfo = ActivityManager.RunningAppProcessInfo()
ActivityManager.getMyMemoryState(appProcessInfo);
return ((appProcessInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) or
(appProcessInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE))
}
fun isDeviceLocked(context: Context): Boolean {
val isLocked: Boolean
val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
val inKeyguardRestrictedInputMode = keyguardManager.inKeyguardRestrictedInputMode()
if (inKeyguardRestrictedInputMode) {
isLocked = true
} else {
val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
isLocked = !powerManager.isInteractive
}
Log.d("Baresip", "Now device is ${if (isLocked) "locked" else "unlocked"}")
return isLocked
}
external fun cmd_exec(cmd: String): Int external fun cmd_exec(cmd: String): Int
external fun uri_decode(uri: String): Boolean external fun uri_decode(uri: String): Boolean
external fun audio_codecs(): String external fun audio_codecs(): String