Allow answering call without unlocking the device

This commit is contained in:
Juha Heinanen
2022-01-09 10:47:44 +02:00
parent 84b132cc86
commit f6a81bc9bd
5 changed files with 136 additions and 55 deletions

View File

@ -61,6 +61,12 @@
<data android:scheme="sip" />
</intent-filter>
</activity>
<activity
android:name=".ProxyActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:launchMode="singleTop"
android:noHistory="true" >
</activity>
<activity
android:name=".AccountsActivity"
android:configChanges="orientation|keyboardHidden|screenSize"

View File

@ -72,6 +72,7 @@ class BaresipService: Service() {
@SuppressLint("WakelockTimeout")
override fun onCreate() {
super.onCreate()
Log.d(TAG, "At onCreate")
@ -229,7 +230,9 @@ class BaresipService: Service() {
}
}
this.registerReceiver(screenReceiver, IntentFilter(Intent.ACTION_SCREEN_ON))
this.registerReceiver(screenReceiver, IntentFilter().apply {
addAction(Intent.ACTION_SCREEN_ON)
})
tm = getSystemService(Context.TELECOM_SERVICE) as TelecomManager
@ -318,8 +321,6 @@ class BaresipService: Service() {
this.registerReceiver(bluetoothReceiver, filter)
}
super.onCreate()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
@ -503,8 +504,8 @@ class BaresipService: Service() {
}
override fun onDestroy() {
Log.d(TAG, "At Baresip Service onDestroy")
super.onDestroy()
Log.d(TAG, "At Baresip Service onDestroy")
this.unregisterReceiver(bluetoothReceiver)
this.unregisterReceiver(hotSpotReceiver)
this.unregisterReceiver(screenReceiver)
@ -642,9 +643,15 @@ class BaresipService: Service() {
}
}
if (!Utils.isVisible()) {
val intent = Intent(applicationContext, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or
Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
val intent = if (isMainAlive)
Intent(applicationContext, ProxyActivity::class.java)
else
Intent(applicationContext, MainActivity::class.java)
intent.flags = if (isMainAlive)
Intent.FLAG_ACTIVITY_NEW_TASK
else
Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP or
Intent.FLAG_ACTIVITY_NEW_TASK
intent.putExtra("action", "call show")
.putExtra("callp", callp)
val pi = if (VERSION.SDK_INT >= 23)
@ -657,17 +664,18 @@ class BaresipService: Service() {
val caller = Utils.friendlyUri(ContactsActivity.contactName(peerUri),
Utils.aorDomain(aor))
nb.setSmallIcon(R.drawable.ic_stat_call)
.setColor(ContextCompat.getColor(this, R.color.colorBaresip))
.setContentIntent(pi)
.setCategory(Notification.CATEGORY_CALL)
.setAutoCancel(true)
.setOngoing(true)
.setContentTitle(getString(R.string.incoming_call_from))
.setContentText(caller)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setFullScreenIntent(pi, true)
.setColor(ContextCompat.getColor(this, R.color.colorBaresip))
.setContentIntent(pi)
.setCategory(Notification.CATEGORY_CALL)
.setAutoCancel(false)
.setOngoing(true)
.setContentTitle(getString(R.string.incoming_call_from))
.setContentText(caller)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setFullScreenIntent(pi, true)
if (VERSION.SDK_INT < 26) {
@Suppress("DEPRECATION")
nb.setVibrate(LongArray(0))
@ -1447,6 +1455,7 @@ class BaresipService: Service() {
var sipTrace = false
var callActionUri = ""
var isMainVisible = false
var isMainAlive = false
var isMicMuted = false
val uas = ArrayList<UserAgent>()

View File

@ -121,12 +121,15 @@ class MainActivity : AppCompatActivity() {
if (intent?.action == ACTION_CALL && !BaresipService.isServiceRunning)
BaresipService.callActionUri = URLDecoder.decode(intent.data.toString(), "UTF-8")
kgm = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
window.addFlags(WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES)
setContentView(binding.root)
// Must be done after view has been created
Utils.setShowWhenLocked(this, true)
Utils.setTurnScreenOn(this, true)
Utils.requestDismissKeyguard(this)
setSupportActionBar(binding.toolbar)
layout = binding.mainActivityLayout
@ -154,6 +157,7 @@ class MainActivity : AppCompatActivity() {
imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
nm = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
am = getSystemService(AUDIO_SERVICE) as AudioManager
kgm = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
serviceEventReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
@ -161,16 +165,20 @@ class MainActivity : AppCompatActivity() {
intent.getStringArrayListExtra("params")!!)
}
}
LocalBroadcastManager.getInstance(this).registerReceiver(serviceEventReceiver,
IntentFilter("service event"))
screenEventReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val event = intent.getStringExtra("event")!!
if (event == Intent.ACTION_SCREEN_ON && !Call.isStatus("incoming"))
dismissKeyguard()
if (event == Intent.ACTION_SCREEN_ON && Call.calls().size == 0) {
Log.d(TAG, "setShowWhenLocked == falsed")
Utils.setShowWhenLocked(this@MainActivity, false)
}
}
}
LocalBroadcastManager.getInstance(this).registerReceiver(screenEventReceiver,
IntentFilter("screen event"))
@ -603,7 +611,7 @@ class MainActivity : AppCompatActivity() {
if (intent.hasExtra("action"))
// MainActivity was not visible when call, message, or transfer request came in
handleIntent(intent)
handleIntent(intent, intent.getStringExtra("action"))
else
if (!BaresipService.isServiceRunning)
if (File(filesDir.absolutePath + "/accounts").exists()) {
@ -629,11 +637,13 @@ class MainActivity : AppCompatActivity() {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.RECORD_AUDIO),
MIC_PERMISSION_REQUEST_CODE)
BaresipService.isMainAlive = true
} // OnCreate
override fun onStart() {
Log.d(TAG, "Main onStart")
super.onStart()
Log.d(TAG, "Main onStart")
}
override fun onResume() {
@ -642,9 +652,10 @@ class MainActivity : AppCompatActivity() {
nm.cancelAll()
BaresipService.isMainVisible = true
when (resumeAction) {
"call show" ->
handleServiceEvent("call incoming",
arrayListOf(resumeCall!!.ua.uap, resumeCall!!.callp))
"call show" -> {
handleServiceEvent ("call incoming",
arrayListOf(resumeCall!!.ua.uap, resumeCall!!.callp))
}
"call answer" -> {
answerButton.performClick()
showCall(resumeCall!!.ua)
@ -692,32 +703,38 @@ class MainActivity : AppCompatActivity() {
}
override fun onPause() {
super.onPause()
Log.d(TAG, "Main onPause")
Utils.addActivity("main")
BaresipService.isMainVisible = false
saveCallUri()
super.onPause()
}
override fun onStop() {
Log.d(TAG, "Main onStop")
super.onStop()
Log.d(TAG, "Main onStop")
}
override fun onDestroy() {
Log.d(TAG, "Main onDestroy")
LocalBroadcastManager.getInstance(this).unregisterReceiver(serviceEventReceiver)
BaresipService.activities.clear()
super.onDestroy()
Log.d(TAG, "Main onDestroy")
LocalBroadcastManager.getInstance(this).unregisterReceiver(screenEventReceiver)
LocalBroadcastManager.getInstance(this).unregisterReceiver(serviceEventReceiver)
BaresipService.activities.clear()
BaresipService.isMainAlive = false
}
override fun onNewIntent(intent: Intent) {
// Called when MainActivity already exists at the top of current task
super.onNewIntent(intent)
resumeAction = ""
resumeUri = ""
Log.d(TAG, "onNewIntent ${intent.action} ${intent.data}")
if (intent.action == ACTION_CALL) {
Log.d(TAG, "onNewIntent $ACTION_CALL ${intent.data}")
if (Call.calls().isNotEmpty() || UserAgent.uas().isEmpty()) {
return
}
@ -746,13 +763,14 @@ class MainActivity : AppCompatActivity() {
}
}
} else {
if (intent.getStringExtra("action") != null)
handleIntent(intent)
val action = intent.getStringExtra("action")
Log.d(TAG, "onNewIntent action `$action'")
if (action != null)
handleIntent(intent, action)
}
}
private fun handleIntent(intent: Intent) {
val action = intent.getStringExtra("action")
private fun handleIntent(intent: Intent, action: String?) {
Log.d(TAG, "Handling intent '$action'")
when (action) {
"accounts" -> {
@ -765,7 +783,6 @@ class MainActivity : AppCompatActivity() {
}
"call" -> {
if (Call.calls().isNotEmpty()) {
Toast.makeText(applicationContext, getString(R.string.call_already_active),
Toast.LENGTH_SHORT).show()
return
@ -1088,9 +1105,8 @@ class MainActivity : AppCompatActivity() {
Toast.LENGTH_LONG).show()
}
restoreActivities()
if (Build.VERSION.SDK_INT >= 22 && kgm.isDeviceLocked && kgm.isKeyguardSecure) {
dismissKeyguard()
}
if (Build.VERSION.SDK_INT >= 22 && kgm.isDeviceLocked)
moveTaskToBack(true)
}
"message", "message show", "message reply" -> {
val peer = params[1]
@ -1918,20 +1934,6 @@ class MainActivity : AppCompatActivity() {
}
}
@Suppress("DEPRECATION")
private fun dismissKeyguard() {
Log.d(TAG, "Dismissing keyguard")
if (Build.VERSION.SDK_INT >= 27) {
setShowWhenLocked(true)
setTurnScreenOn(true)
kgm.requestDismissKeyguard(this, null)
} else {
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD)
}
}
companion object {
var accountRequest: ActivityResultLauncher<Intent>? = null

View File

@ -0,0 +1,30 @@
package com.tutpro.baresip
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
class ProxyActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Utils.setShowWhenLocked(this, true)
Utils.setTurnScreenOn(this, true)
Log.d(TAG, "ProxyActivity onCreate")
val intent = Intent(applicationContext, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or
Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
intent.putExtras(getIntent())
startActivity(intent)
finish()
}
}

View File

@ -1,5 +1,7 @@
package com.tutpro.baresip
import android.app.Activity
import android.app.KeyguardManager
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
@ -18,6 +20,7 @@ import android.provider.OpenableColumns
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import android.view.WindowManager
import android.widget.TextView
import androidx.activity.result.ActivityResultLauncher
import androidx.annotation.RequiresApi
@ -660,6 +663,37 @@ object Utils {
BaresipService.activities.add(0, activity)
}
@Suppress("DEPRECATION")
fun setShowWhenLocked(activity: Activity, show: Boolean) {
when {
Build.VERSION.SDK_INT >= 27 -> activity.setShowWhenLocked(show)
show -> activity.window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED)
else -> activity.window.clearFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED)
}
}
fun setTurnScreenOn(activity: Activity, turn: Boolean) {
if (Build.VERSION.SDK_INT >= 27) {
activity.setTurnScreenOn(turn)
} else
@Suppress("DEPRECATION")
if (turn) {
activity.window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)
} else {
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)
}
}
@Suppress("DEPRECATION")
fun requestDismissKeyguard(activity: Activity) {
if (Build.VERSION.SDK_INT >= 26) {
val keyguardManager = activity.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
keyguardManager.requestDismissKeyguard(activity, null)
} else {
activity.window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD)
}
}
@Suppress("unused")
fun darkTheme(ctx: Context): Boolean {
return ctx.resources?.configuration?.uiMode?.and(Configuration.UI_MODE_NIGHT_MASK) ==