From b016811a16d0e1eb483c7d6cd3c1c955799add06 Mon Sep 17 00:00:00 2001 From: Juha Heinanen Date: Wed, 25 Jul 2018 14:00:17 +0300 Subject: [PATCH] message related enhancements --- app/build.gradle | 4 +- app/src/main/cpp/baresip.c | 33 +++++++++---- .../com/tutpro/baresip/BaresipService.kt | 12 ++++- .../kotlin/com/tutpro/baresip/MainActivity.kt | 9 ++-- .../main/kotlin/com/tutpro/baresip/Message.kt | 2 +- .../com/tutpro/baresip/MessageActivity.kt | 19 ++++---- .../com/tutpro/baresip/MessagesActivity.kt | 45 +++++++++++++++++- app/src/main/res/drawable/arrow_up_yellow.png | Bin 0 -> 297 bytes 8 files changed, 96 insertions(+), 28 deletions(-) create mode 100644 app/src/main/res/drawable/arrow_up_yellow.png diff --git a/app/build.gradle b/app/build.gradle index a7ab343c..185c0c39 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,8 +8,8 @@ android { applicationId = 'com.tutpro.baresip' minSdkVersion 21 targetSdkVersion 26 - versionCode = 8 - versionName = '1.0' + versionCode = 9 + versionName = '2.0' ndk { abiFilters 'armeabi-v7a' } diff --git a/app/src/main/cpp/baresip.c b/app/src/main/cpp/baresip.c index 43ee9e25..cc3c69f5 100644 --- a/app/src/main/cpp/baresip.c +++ b/app/src/main/cpp/baresip.c @@ -234,17 +234,30 @@ static void send_resp_handler(int err, const struct sip_msg *msg, void *arg) { (void)arg; - LOGD("received message response %u\n", msg->scode); - if (err) { - (void)re_fprintf(stderr, " \x1b[31m%m\x1b[;m\n", err); + LOGD("send_response_handler received error %d\n", err); return; } - if (msg->scode >= 300) { - (void)re_fprintf(stderr, " \x1b[31m%u %r\x1b[;m\n", - msg->scode, &msg->reason); + LOGD("send_response_handler received response %u at %s\n", msg->scode, (char *)arg); + + UpdateContext *pctx = (UpdateContext*)(&g_ctx); + JavaVM *javaVM = pctx->javaVM; + JNIEnv *env; + jint res = (*javaVM)->GetEnv(javaVM, (void**)&env, JNI_VERSION_1_6); + if (res != JNI_OK) { + res = (*javaVM)->AttachCurrentThread(javaVM, &env, NULL); + if (JNI_OK != res) { + LOGE("Failed to AttachCurrentThread, ErrorCode = %d", res); + return; + } } + jmethodID methodId = (*env)->GetMethodID(env, pctx->mainActivityClz, + "messageResponse", "(ILjava/lang/String;)V"); + jstring javaTime = (*env)->NewStringUTF(env, (char *)arg); + (*env)->CallVoidMethod(env, pctx->mainActivityObj, methodId, msg->scode, javaTime); + (*env)->DeleteLocalRef(env, javaTime); + } #include @@ -966,15 +979,17 @@ Java_com_tutpro_baresip_MainActivity_call_1send_1digit(JNIEnv *env, jobject thiz JNIEXPORT jint JNICALL Java_com_tutpro_baresip_MessageActivity_message_1send(JNIEnv *env, jobject thiz, jstring javaUA, - jstring javaPeer, jstring javaMsg) { + jstring javaPeer, jstring javaMsg, + jstring javaTime) { struct ua *ua; const char *native_ua = (*env)->GetStringUTFChars(env, javaUA, 0); const char *native_peer = (*env)->GetStringUTFChars(env, javaPeer, 0); const char *native_msg = (*env)->GetStringUTFChars(env, javaMsg, 0); + const char *native_time = (*env)->GetStringUTFChars(env, javaTime, 0); - LOGD("sending message from ua %s to %s\n", native_ua, native_peer); + LOGD("sending message from ua %s to %s at %s\n", native_ua, native_peer, native_time); ua = (struct ua *)strtoul(native_ua, NULL, 10); - int err = message_send(ua, native_peer, native_msg, send_resp_handler, NULL); + int err = message_send(ua, native_peer, native_msg, send_resp_handler, (void *)native_time); if (err) { LOGW("message_send failed with error %d\n", err); } diff --git a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt index 4b5b583d..a2f00230 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt @@ -319,14 +319,13 @@ class BaresipService: Service() { @Keep fun messageEvent(uap: String, peer: String, msg: ByteArray) { - Log.d(LOG_TAG, "message event $uap/$peer") var s = "Decoding of message failed!" try { s = String(msg, StandardCharsets.UTF_8) - Log.d(LOG_TAG, "UTF-8 $s") } catch (e: Exception) { Log.e(LOG_TAG, "UTF-8 decode failed") } + Log.d(LOG_TAG, "Message event $uap/$peer/$s") val timeStamp = System.currentTimeMillis().toString() if (!Utils.isVisible()) { val cnb = NotificationCompat.Builder(this, HIGH_CHANNEL_ID) @@ -383,6 +382,15 @@ class BaresipService: Service() { LocalBroadcastManager.getInstance(this).sendBroadcast(intent) } + @Keep + fun messageResponse(responseCode: Int, time: String) { + Log.d(LOG_TAG, "Message response $responseCode at $time") + val intent = Intent("message response") + intent.putExtra("response code", responseCode) + intent.putExtra("time", time) + LocalBroadcastManager.getInstance(this).sendBroadcast(intent) + } + private fun updateStatusNotification() { val contentView = RemoteViews(getPackageName(), R.layout.status_notification) for (i: Int in 0 .. 5) { diff --git a/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt index 781accda..bf154ba5 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt @@ -589,12 +589,12 @@ class MainActivity : AppCompatActivity() { val new_message = Message(aor, peer_uri, R.drawable.arrow_down_green, msg, time.toLong(), true) Log.d("Baresip", "Incoming message $aor/$peer_uri/$msg") - messages.add(new_message) + MessagesActivity.addMessage(new_message) if (Utils.isVisible()) { if (ua != uas[aorSpinner.selectedItemPosition]) aorSpinner.setSelection(account_index) val i = Intent(applicationContext, MessagesActivity::class.java) - i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) + i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) val b = Bundle() b.putString("aor", ua.account.aor) i.putExtras(b) @@ -642,6 +642,7 @@ class MainActivity : AppCompatActivity() { } b.putString("aor", aor) b.putString("peer", intent.getStringExtra("peer")) + b.putBoolean("reply", true) i.putExtras(b) startActivityForResult(i, MESSAGES_CODE) } @@ -663,13 +664,13 @@ class MainActivity : AppCompatActivity() { override fun onPause() { super.onPause() - Log.d("Baresip", "Paused") + // Log.d("Baresip", "Paused") visible = false } override fun onResume() { super.onResume() - Log.d("Baresip", "Resumed") + // Log.d("Baresip", "Resumed") imm.hideSoftInputFromWindow(callee.windowToken, 0) visible = true if ((answerCall != "") && (layout.childCount > 8)) { diff --git a/app/src/main/kotlin/com/tutpro/baresip/Message.kt b/app/src/main/kotlin/com/tutpro/baresip/Message.kt index 9d200950..3128ba23 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Message.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Message.kt @@ -2,6 +2,6 @@ package com.tutpro.baresip import java.io.Serializable -class Message(val aor: String, val peerURI: String, val direction: Int, val message: String, +class Message(val aor: String, val peerURI: String, var direction: Int, val message: String, val timeStamp: Long, var new: Boolean): Serializable { } diff --git a/app/src/main/kotlin/com/tutpro/baresip/MessageActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/MessageActivity.kt index 6d85f7ac..a82e0cc6 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/MessageActivity.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/MessageActivity.kt @@ -24,6 +24,7 @@ class MessageActivity : AppCompatActivity() { val aor = intent.extras.getString("aor") val peerURI = intent.extras.getString("peer") + val reply = intent.extras.getBoolean("reply") val ua = Account.findUa(aor) if (ua == null) { @@ -38,15 +39,16 @@ class MessageActivity : AppCompatActivity() { receiver = findViewById(R.id.receiver) as AutoCompleteTextView imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager - - if (peerURI == "") { + if (reply) + title.text = "Message reply to ..." + else title.text = "Message to ..." + if (peerURI == "") { receiver.threshold = 2 receiver.setAdapter(ArrayAdapter(this, android.R.layout.select_dialog_item, ContactsActivity.contacts.map { Contact -> Contact.name })) receiver.requestFocus() } else { - title.text = "Reply to ..." receiver.setText(ContactsActivity.contactName(peerURI), false) message.requestFocus() } @@ -66,14 +68,15 @@ class MessageActivity : AppCompatActivity() { if (msg.length > 0) { imm.hideSoftInputFromWindow(receiver.getWindowToken(), 0) imm.hideSoftInputFromWindow(message.getWindowToken(), 0) - val res = message_send(ua!!.uap, uri, msg) + val time = System.currentTimeMillis() + val res = message_send(ua!!.uap, uri, msg, time.toString()) if (res != 0) { Toast.makeText(getApplicationContext(), "Sending of message failed!", Toast.LENGTH_SHORT).show() } else { - val new_message = Message(aor, uri, R.drawable.arrow_up_green, msg, - System.currentTimeMillis(), false) - MainActivity.messages.add(new_message) + val new_message = Message(aor, uri, R.drawable.arrow_up_yellow, msg, time, + false) + MessagesActivity.addMessage(new_message) MessagesActivity.uaMessages.add(0, new_message) val i = Intent() setResult(Activity.RESULT_OK, i) @@ -97,6 +100,6 @@ class MessageActivity : AppCompatActivity() { return true } - external fun message_send(uap: String, peer_uri: String, message: String) : Int + external fun message_send(uap: String, peer_uri: String, message: String, time: String) : Int } diff --git a/app/src/main/kotlin/com/tutpro/baresip/MessagesActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/MessagesActivity.kt index 03a6ae70..05bb28e0 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/MessagesActivity.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/MessagesActivity.kt @@ -1,9 +1,9 @@ package com.tutpro.baresip import android.app.Activity -import android.content.DialogInterface -import android.content.Intent +import android.content.* import android.os.Bundle +import android.support.v4.content.LocalBroadcastManager import android.support.v7.app.AlertDialog import android.support.v7.app.AppCompatActivity import android.util.Log @@ -22,6 +22,7 @@ class MessagesActivity: AppCompatActivity() { internal lateinit var aor: String internal lateinit var mlAdapter: MessageListAdapter internal lateinit var plusButton: ImageButton + internal lateinit var serviceEventReceiver: BroadcastReceiver public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -42,6 +43,7 @@ class MessagesActivity: AppCompatActivity() { val b = Bundle() b.putString("aor", aor) b.putString("peer", uaMessages[pos].peerURI) + b.putBoolean("reply", uaMessages[pos].direction == R.drawable.arrow_down_green) i.putExtras(b) startActivityForResult(i, MainActivity.MESSAGE_CODE) } @@ -89,16 +91,27 @@ class MessagesActivity: AppCompatActivity() { val b = Bundle() b.putString("aor", aor) b.putString("peer", peer) + b.putBoolean("reply", true) i.putExtras(b) startActivityForResult(i, MainActivity.MESSAGE_CODE) } + serviceEventReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + handleMessageResponse(intent.getIntExtra("response code", 0), + intent.getStringExtra("time")) + } + } + LocalBroadcastManager.getInstance(this).registerReceiver(serviceEventReceiver, + IntentFilter("message response")) + } override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { android.R.id.home -> { Log.d("Baresip", "Back array was pressed at Messages") + saveMessages() val i = Intent() setResult(Activity.RESULT_CANCELED, i) finish() @@ -108,6 +121,7 @@ class MessagesActivity: AppCompatActivity() { } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + Log.d("Baresip", "onActivityResult at Messages") when (requestCode) { MainActivity.MESSAGE_CODE -> { if (resultCode == RESULT_OK) { @@ -117,6 +131,22 @@ class MessagesActivity: AppCompatActivity() { } } + private fun handleMessageResponse(responseCode: Int, time: String) { + if (responseCode < 300) + updateMessageDirection(time.toLong(), R.drawable.arrow_up_green) + else + updateMessageDirection(time.toLong(), R.drawable.arrow_up_red) + mlAdapter.notifyDataSetChanged() + } + + fun updateMessageDirection(timeStamp: Long, direction: Int) { + for (m in uaMessages.reversed()) + if (m.timeStamp == timeStamp) { + m.direction = direction + return + } + } + private fun uaMessages(aor: String) : ArrayList { val res = ArrayList() for (m in MainActivity.messages.reversed()) { @@ -149,6 +179,17 @@ class MessagesActivity: AppCompatActivity() { } } + fun addMessage(message: Message) { + if ((MainActivity.messages.filter{it.aor == message.aor}).size >= + MainActivity.MESSAGE_HISTORY_SIZE) + for (i in MainActivity.messages.indices) + if (MainActivity.messages[i].aor == message.aor) { + MainActivity.messages.removeAt(i) + break + } + MainActivity.messages.add(message) + } + fun saveMessages() { val file = File(MainActivity.filesPath, "messages") try { diff --git a/app/src/main/res/drawable/arrow_up_yellow.png b/app/src/main/res/drawable/arrow_up_yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..977cd974259c0ec62a9fb40db25d04b36e7ba1ce GIT binary patch literal 297 zcmeAS@N?(olHy`uVBq!ia0vp^{6H+i!3HFQj;9L&DYhhUcNd2LAh=-f^2tCE&H|6f zVg?3oVGw3ym^DWND9B#o>Fdh=h+Tq@NvQfrZzoV_o2QFoh{fr*lMVS89Yxyq-|ToJ z=A?czYIV3p!@0yGl2h~^3uJ8-)^N#id3f2TX~W4&8hcVcJ^MTJ{n?a%l0S9^+&UHW zvWCfDbZTa7fyjf>p18H%`Um7Tu<#w=%wW<@m>~3el`MDa!Z%a*ZR*^^zjsBGdf}Oc zmqNEqY+vZV>cLc_V56lxJ9?^?ty%S;Z_@EUZ0>XIZ(pm}vG>Tk*vC^Wn2uNL{(h$T q_o4dphT