mirror of
https://github.com/SimpleMobileTools/Simple-Dialer.git
synced 2025-06-05 21:49:23 +02:00
create conference
This commit is contained in:
@ -23,9 +23,7 @@ import com.simplemobiletools.commons.helpers.isOreoMr1Plus
|
|||||||
import com.simplemobiletools.commons.helpers.isOreoPlus
|
import com.simplemobiletools.commons.helpers.isOreoPlus
|
||||||
import com.simplemobiletools.dialer.R
|
import com.simplemobiletools.dialer.R
|
||||||
import com.simplemobiletools.dialer.extensions.*
|
import com.simplemobiletools.dialer.extensions.*
|
||||||
import com.simplemobiletools.dialer.helpers.CallContactAvatarHelper
|
import com.simplemobiletools.dialer.helpers.*
|
||||||
import com.simplemobiletools.dialer.helpers.CallManager
|
|
||||||
import com.simplemobiletools.dialer.helpers.CallManagerListener
|
|
||||||
import com.simplemobiletools.dialer.models.CallContact
|
import com.simplemobiletools.dialer.models.CallContact
|
||||||
import kotlinx.android.synthetic.main.activity_call.*
|
import kotlinx.android.synthetic.main.activity_call.*
|
||||||
import kotlinx.android.synthetic.main.dialpad.*
|
import kotlinx.android.synthetic.main.dialpad.*
|
||||||
@ -57,6 +55,11 @@ class CallActivity : SimpleActivity() {
|
|||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_call)
|
setContentView(R.layout.activity_call)
|
||||||
|
|
||||||
|
if (CallManager.call == null) {
|
||||||
|
finish()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
updateTextColors(call_holder)
|
updateTextColors(call_holder)
|
||||||
initButtons()
|
initButtons()
|
||||||
|
|
||||||
@ -65,13 +68,13 @@ class CallActivity : SimpleActivity() {
|
|||||||
addLockScreenFlags()
|
addLockScreenFlags()
|
||||||
|
|
||||||
CallManager.addListener(callCallback)
|
CallManager.addListener(callCallback)
|
||||||
|
|
||||||
|
updateCallContactInfo(CallManager.getPrimaryCall())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
updateCallState(CallManager.getPrimaryCall())
|
updateState()
|
||||||
updateCallOnHoldState(CallManager.getSecondaryCall())
|
|
||||||
updateCallContactInfo(CallManager.getPrimaryCall())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
@ -171,7 +174,10 @@ class CallActivity : SimpleActivity() {
|
|||||||
dialpad_hashtag_holder.setOnClickListener { dialpadPressed('#') }
|
dialpad_hashtag_holder.setOnClickListener { dialpadPressed('#') }
|
||||||
|
|
||||||
dialpad_wrapper.setBackgroundColor(getProperBackgroundColor())
|
dialpad_wrapper.setBackgroundColor(getProperBackgroundColor())
|
||||||
arrayOf(call_toggle_microphone, call_toggle_speaker, call_dialpad, dialpad_close, call_sim_image).forEach {
|
arrayOf(
|
||||||
|
call_toggle_microphone, call_toggle_speaker, call_dialpad, dialpad_close,
|
||||||
|
call_sim_image, call_toggle_hold, call_add, call_swap, call_merge, call_manage
|
||||||
|
).forEach {
|
||||||
it.applyColorFilter(getProperTextColor())
|
it.applyColorFilter(getProperTextColor())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,11 +416,23 @@ class CallActivity : SimpleActivity() {
|
|||||||
if (statusTextId != 0) {
|
if (statusTextId != 0) {
|
||||||
call_status_label.text = getString(statusTextId)
|
call_status_label.text = getString(statusTextId)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateState() {
|
||||||
|
val phoneState = CallManager.getPhoneState()
|
||||||
|
if (phoneState is SingleCall) {
|
||||||
|
updateCallState(phoneState.call)
|
||||||
|
updateCallOnHoldState(null)
|
||||||
|
val state = phoneState.call.getStateCompat()
|
||||||
val isSingleCallActionsEnabled = (state == Call.STATE_ACTIVE || state == Call.STATE_DISCONNECTED
|
val isSingleCallActionsEnabled = (state == Call.STATE_ACTIVE || state == Call.STATE_DISCONNECTED
|
||||||
|| state == Call.STATE_DISCONNECTING || state == Call.STATE_HOLDING)
|
|| state == Call.STATE_DISCONNECTING || state == Call.STATE_HOLDING)
|
||||||
setActionButtonEnabled(call_toggle_hold, isSingleCallActionsEnabled)
|
setActionButtonEnabled(call_toggle_hold, isSingleCallActionsEnabled)
|
||||||
setActionButtonEnabled(call_add, isSingleCallActionsEnabled)
|
setActionButtonEnabled(call_add, isSingleCallActionsEnabled)
|
||||||
|
call_manage.beVisibleIf(phoneState.call.isConference())
|
||||||
|
} else if (phoneState is TwoCalls) {
|
||||||
|
updateCallState(phoneState.active)
|
||||||
|
updateCallOnHoldState(phoneState.onHold)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateCallOnHoldState(call: Call?) {
|
private fun updateCallOnHoldState(call: Call?) {
|
||||||
@ -427,11 +445,16 @@ class CallActivity : SimpleActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
on_hold_status_holder.beVisibleIf(hasCallOnHold)
|
on_hold_status_holder.beVisibleIf(hasCallOnHold)
|
||||||
controls_single_call.beVisibleIf(!hasCallOnHold) // TODO and not conference
|
controls_single_call.beVisibleIf(!hasCallOnHold)
|
||||||
controls_two_calls.beVisibleIf(hasCallOnHold)
|
controls_two_calls.beVisibleIf(hasCallOnHold)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateCallContactInfo(call: Call?) {
|
private fun updateCallContactInfo(call: Call?) {
|
||||||
|
if (call.isConference()) {
|
||||||
|
caller_avatar.setImageDrawable(null)
|
||||||
|
caller_number.text = null
|
||||||
|
caller_name_label.text = getString(R.string.conference)
|
||||||
|
} else {
|
||||||
CallManager.getCallContact(applicationContext, call) { contact ->
|
CallManager.getCallContact(applicationContext, call) { contact ->
|
||||||
callContact = contact
|
callContact = contact
|
||||||
val avatar = callContactAvatarHelper.getCallContactAvatar(contact)
|
val avatar = callContactAvatarHelper.getCallContactAvatar(contact)
|
||||||
@ -441,6 +464,7 @@ class CallActivity : SimpleActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun acceptCall() {
|
private fun acceptCall() {
|
||||||
CallManager.accept()
|
CallManager.accept()
|
||||||
@ -502,17 +526,12 @@ class CallActivity : SimpleActivity() {
|
|||||||
|
|
||||||
private val callCallback = object : CallManagerListener {
|
private val callCallback = object : CallManagerListener {
|
||||||
override fun onStateChanged(call: Call, state: Int) {
|
override fun onStateChanged(call: Call, state: Int) {
|
||||||
updateCallState(call)
|
updateState()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCallPutOnHold(call: Call?) {
|
override fun onPrimaryCallChanged(call: Call) {
|
||||||
updateCallOnHoldState(call)
|
updateCallContactInfo(call)
|
||||||
}
|
updateState()
|
||||||
|
|
||||||
override fun onCallsChanged(active: Call, onHold: Call?) {
|
|
||||||
updateCallState(active)
|
|
||||||
updateCallOnHoldState(onHold)
|
|
||||||
updateCallContactInfo(active)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,8 @@ import com.simplemobiletools.commons.helpers.MyContactsContentProvider
|
|||||||
import com.simplemobiletools.commons.helpers.SimpleContactsHelper
|
import com.simplemobiletools.commons.helpers.SimpleContactsHelper
|
||||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||||
import com.simplemobiletools.dialer.extensions.getStateCompat
|
import com.simplemobiletools.dialer.extensions.getStateCompat
|
||||||
|
import com.simplemobiletools.dialer.extensions.hasCapability
|
||||||
|
import com.simplemobiletools.dialer.extensions.isConference
|
||||||
import com.simplemobiletools.dialer.models.CallContact
|
import com.simplemobiletools.dialer.models.CallContact
|
||||||
import java.util.concurrent.CopyOnWriteArraySet
|
import java.util.concurrent.CopyOnWriteArraySet
|
||||||
|
|
||||||
@ -28,37 +30,73 @@ class CallManager {
|
|||||||
fun onCallAdded(call: Call) {
|
fun onCallAdded(call: Call) {
|
||||||
this.call = call
|
this.call = call
|
||||||
calls.add(call)
|
calls.add(call)
|
||||||
|
for (listener in listeners) {
|
||||||
|
listener.onPrimaryCallChanged(call)
|
||||||
|
}
|
||||||
call.registerCallback(object : Call.Callback() {
|
call.registerCallback(object : Call.Callback() {
|
||||||
override fun onStateChanged(call: Call, state: Int) {
|
override fun onStateChanged(call: Call, state: Int) {
|
||||||
Log.d(TAG, "onStateChanged: $call")
|
Log.d(TAG, "onStateChanged: $call")
|
||||||
|
updateState()
|
||||||
for (listener in listeners) {
|
for (listener in listeners) {
|
||||||
listener.onStateChanged(call, state)
|
listener.onStateChanged(call, state)
|
||||||
}
|
}
|
||||||
if (state == Call.STATE_HOLDING && calls.size > 1) {
|
|
||||||
for (listener in listeners) {
|
|
||||||
listener.onCallPutOnHold(call)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (state == Call.STATE_ACTIVE && calls.size == 1) {
|
|
||||||
for (listener in listeners) {
|
|
||||||
listener.onCallPutOnHold(null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((state == Call.STATE_CONNECTING || state == Call.STATE_DIALING || state == Call.STATE_ACTIVE) && calls.size > 1) {
|
|
||||||
if (CallManager.call != call) {
|
|
||||||
CallManager.call = call
|
|
||||||
Log.d(TAG, "onCallsChanged")
|
|
||||||
for (listener in listeners) {
|
|
||||||
listener.onCallsChanged(call, getSecondaryCall())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onConferenceableCallsChanged(call: Call, conferenceableCalls: MutableList<Call>) {
|
||||||
|
Log.d(TAG, "onConferenceableCallsChanged: $call, conferenceableCalls size=${conferenceableCalls.size}")
|
||||||
|
updateState()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onCallRemoved(call: Call) {
|
fun onCallRemoved(call: Call) {
|
||||||
calls.remove(call)
|
calls.remove(call)
|
||||||
|
updateState()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getPhoneState(): PhoneState {
|
||||||
|
return when (calls.size) {
|
||||||
|
0 -> {
|
||||||
|
NoCall
|
||||||
|
}
|
||||||
|
1 -> {
|
||||||
|
SingleCall(calls.first())
|
||||||
|
}
|
||||||
|
2 -> {
|
||||||
|
val active = calls.find { it.getStateCompat() == Call.STATE_ACTIVE }
|
||||||
|
val newCall = calls.find { it.getStateCompat() == Call.STATE_CONNECTING || it.getStateCompat() == Call.STATE_DIALING }
|
||||||
|
val onHold = calls.find { it.getStateCompat() == Call.STATE_HOLDING }
|
||||||
|
if (active != null && newCall != null) {
|
||||||
|
TwoCalls(newCall, active)
|
||||||
|
} else if(newCall != null && onHold != null) {
|
||||||
|
TwoCalls(newCall, onHold)
|
||||||
|
} else if(active != null && onHold != null) {
|
||||||
|
TwoCalls(active, onHold)
|
||||||
|
} else {
|
||||||
|
TwoCalls(calls[0], calls[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
SingleCall(calls.find { it.isConference() }!!)
|
||||||
|
// TODO handle the call on hold (outside the conference)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateState() {
|
||||||
|
val primaryCall = when (val phoneState = getPhoneState()) {
|
||||||
|
is NoCall -> null
|
||||||
|
is SingleCall -> phoneState.call
|
||||||
|
is TwoCalls -> phoneState.active
|
||||||
|
}
|
||||||
|
if (primaryCall == null) {
|
||||||
|
call = null
|
||||||
|
} else if (primaryCall != call) {
|
||||||
|
call = primaryCall
|
||||||
|
for (listener in listeners) {
|
||||||
|
listener.onPrimaryCallChanged(primaryCall)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPrimaryCall(): Call? {
|
fun getPrimaryCall(): Call? {
|
||||||
@ -104,14 +142,14 @@ class CallManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun merge() {
|
fun merge() {
|
||||||
// val conferenceableCalls = call!!.conferenceableCalls
|
val conferenceableCalls = call!!.conferenceableCalls
|
||||||
// if (conferenceableCalls.isNotEmpty()) {
|
if (conferenceableCalls.isNotEmpty()) {
|
||||||
// call!!.conference(conferenceableCalls.first())
|
call!!.conference(conferenceableCalls.first())
|
||||||
// } else {
|
} else {
|
||||||
// if (call!!.hasCapability(Call.Details.CAPABILITY_MERGE_CONFERENCE)) {
|
if (call!!.hasCapability(Call.Details.CAPABILITY_MERGE_CONFERENCE)) {
|
||||||
// call!!.mergeConference()
|
call!!.mergeConference()
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addListener(listener: CallManagerListener) {
|
fun addListener(listener: CallManagerListener) {
|
||||||
@ -203,6 +241,10 @@ class CallManager {
|
|||||||
|
|
||||||
interface CallManagerListener {
|
interface CallManagerListener {
|
||||||
fun onStateChanged(call: Call, state: Int)
|
fun onStateChanged(call: Call, state: Int)
|
||||||
fun onCallPutOnHold(call: Call?)
|
fun onPrimaryCallChanged(call: Call)
|
||||||
fun onCallsChanged(active: Call, onHold: Call?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sealed class PhoneState
|
||||||
|
object NoCall : PhoneState()
|
||||||
|
class SingleCall(val call: Call?) : PhoneState()
|
||||||
|
class TwoCalls(val active: Call, val onHold: Call) : PhoneState()
|
||||||
|
@ -46,8 +46,6 @@ class CallService : InCallService() {
|
|||||||
CallManager.inCallService = null
|
CallManager.inCallService = null
|
||||||
callNotificationManager.cancelNotification()
|
callNotificationManager.cancelNotification()
|
||||||
} else {
|
} else {
|
||||||
// TODO if left more than 1
|
|
||||||
CallManager.call = CallManager.calls.first()
|
|
||||||
callNotificationManager.setupNotification()
|
callNotificationManager.setupNotification()
|
||||||
startActivity(CallActivity.getStartIntent(this))
|
startActivity(CallActivity.getStartIntent(this))
|
||||||
}
|
}
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
|
||||||
android:viewportHeight="24" android:viewportWidth="24"
|
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<path android:fillColor="@android:color/white"
|
|
||||||
android:fillType="evenOdd" android:pathData="M16.67,13.13C18.04,14.06 19,15.32 19,17v3h4v-3C23,14.82 19.43,13.53 16.67,13.13z"/>
|
|
||||||
<path android:fillColor="@android:color/white"
|
|
||||||
android:fillType="evenOdd" android:pathData="M9,8m-4,0a4,4 0,1 1,8 0a4,4 0,1 1,-8 0"/>
|
|
||||||
<path android:fillColor="@android:color/white"
|
|
||||||
android:fillType="evenOdd" android:pathData="M15,12c2.21,0 4,-1.79 4,-4c0,-2.21 -1.79,-4 -4,-4c-0.47,0 -0.91,0.1 -1.33,0.24C14.5,5.27 15,6.58 15,8s-0.5,2.73 -1.33,3.76C14.09,11.9 14.53,12 15,12z"/>
|
|
||||||
<path android:fillColor="@android:color/white"
|
|
||||||
android:fillType="evenOdd" android:pathData="M9,13c-2.67,0 -8,1.34 -8,4v3h16v-3C17,14.34 11.67,13 9,13z"/>
|
|
||||||
</vector>
|
|
@ -118,6 +118,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="@dimen/normal_margin"
|
android:layout_margin="@dimen/normal_margin"
|
||||||
|
android:contentDescription="@null"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
@ -203,6 +204,7 @@
|
|||||||
android:layout_height="@dimen/dialpad_button_size"
|
android:layout_height="@dimen/dialpad_button_size"
|
||||||
android:layout_marginTop="@dimen/bigger_margin"
|
android:layout_marginTop="@dimen/bigger_margin"
|
||||||
android:background="?attr/selectableItemBackgroundBorderless"
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:contentDescription="@string/hold_call"
|
||||||
android:padding="@dimen/medium_margin"
|
android:padding="@dimen/medium_margin"
|
||||||
android:src="@drawable/ic_pause_vector"
|
android:src="@drawable/ic_pause_vector"
|
||||||
app:layout_constraintEnd_toStartOf="@id/call_add"
|
app:layout_constraintEnd_toStartOf="@id/call_add"
|
||||||
@ -215,6 +217,7 @@
|
|||||||
android:layout_height="@dimen/dialpad_button_size"
|
android:layout_height="@dimen/dialpad_button_size"
|
||||||
android:layout_marginTop="@dimen/bigger_margin"
|
android:layout_marginTop="@dimen/bigger_margin"
|
||||||
android:background="?attr/selectableItemBackgroundBorderless"
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:contentDescription="@string/call_add"
|
||||||
android:padding="@dimen/medium_margin"
|
android:padding="@dimen/medium_margin"
|
||||||
android:src="@drawable/ic_add_call_vector"
|
android:src="@drawable/ic_add_call_vector"
|
||||||
app:layout_constraintEnd_toEndOf="@id/call_manage"
|
app:layout_constraintEnd_toEndOf="@id/call_manage"
|
||||||
@ -227,6 +230,7 @@
|
|||||||
android:layout_height="@dimen/dialpad_button_size"
|
android:layout_height="@dimen/dialpad_button_size"
|
||||||
android:layout_marginTop="@dimen/bigger_margin"
|
android:layout_marginTop="@dimen/bigger_margin"
|
||||||
android:background="?attr/selectableItemBackgroundBorderless"
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:contentDescription="@string/call_manage"
|
||||||
android:padding="@dimen/medium_margin"
|
android:padding="@dimen/medium_margin"
|
||||||
android:src="@drawable/ic_people_vector"
|
android:src="@drawable/ic_people_vector"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
@ -240,6 +244,7 @@
|
|||||||
android:layout_height="@dimen/dialpad_button_size"
|
android:layout_height="@dimen/dialpad_button_size"
|
||||||
android:layout_marginTop="@dimen/bigger_margin"
|
android:layout_marginTop="@dimen/bigger_margin"
|
||||||
android:background="?attr/selectableItemBackgroundBorderless"
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:contentDescription="@string/call_swap"
|
||||||
android:padding="@dimen/medium_margin"
|
android:padding="@dimen/medium_margin"
|
||||||
android:src="@drawable/ic_call_swap_vector"
|
android:src="@drawable/ic_call_swap_vector"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/call_merge"
|
app:layout_constraintEnd_toStartOf="@+id/call_merge"
|
||||||
@ -254,6 +259,7 @@
|
|||||||
android:layout_height="@dimen/dialpad_button_size"
|
android:layout_height="@dimen/dialpad_button_size"
|
||||||
android:layout_marginTop="@dimen/bigger_margin"
|
android:layout_marginTop="@dimen/bigger_margin"
|
||||||
android:background="?attr/selectableItemBackgroundBorderless"
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:contentDescription="@string/call_merge"
|
||||||
android:padding="@dimen/medium_margin"
|
android:padding="@dimen/medium_margin"
|
||||||
android:src="@drawable/ic_call_merge_vector"
|
android:src="@drawable/ic_call_merge_vector"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
@ -51,6 +51,12 @@
|
|||||||
<string name="hold_call">Hold call</string>
|
<string name="hold_call">Hold call</string>
|
||||||
<string name="resume_call">Resume call</string>
|
<string name="resume_call">Resume call</string>
|
||||||
<string name="call_on_hold">On Hold</string>
|
<string name="call_on_hold">On Hold</string>
|
||||||
|
<string name="call_swap">Swap calls</string>
|
||||||
|
<string name="call_merge">Merge calls</string>
|
||||||
|
<string name="call_split">Split call</string>
|
||||||
|
<string name="call_add">Add call</string>
|
||||||
|
<string name="call_manage">Manage calls</string>
|
||||||
|
<string name="conference">Conference</string>
|
||||||
|
|
||||||
<!-- Speed dial -->
|
<!-- Speed dial -->
|
||||||
<string name="speed_dial">Speed dial</string>
|
<string name="speed_dial">Speed dial</string>
|
||||||
|
Reference in New Issue
Block a user