mirror of
https://github.com/SimpleMobileTools/Simple-Dialer.git
synced 2025-02-21 22:07:44 +01:00
switch between two calls
This commit is contained in:
parent
a2bff29d59
commit
445e13389e
@ -99,6 +99,7 @@
|
||||
android:excludeFromRecents="true"
|
||||
android:exported="false"
|
||||
android:label="@string/ongoing_call"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="portrait"
|
||||
android:showOnLockScreen="true" />
|
||||
|
||||
|
@ -22,21 +22,21 @@ import com.simplemobiletools.commons.helpers.MINUTE_SECONDS
|
||||
import com.simplemobiletools.commons.helpers.isOreoMr1Plus
|
||||
import com.simplemobiletools.commons.helpers.isOreoPlus
|
||||
import com.simplemobiletools.dialer.R
|
||||
import com.simplemobiletools.dialer.extensions.addCharacter
|
||||
import com.simplemobiletools.dialer.extensions.audioManager
|
||||
import com.simplemobiletools.dialer.extensions.config
|
||||
import com.simplemobiletools.dialer.extensions.getHandleToUse
|
||||
import com.simplemobiletools.dialer.extensions.*
|
||||
import com.simplemobiletools.dialer.helpers.CallContactAvatarHelper
|
||||
import com.simplemobiletools.dialer.helpers.CallManager
|
||||
import com.simplemobiletools.dialer.helpers.CallManagerListener
|
||||
import com.simplemobiletools.dialer.models.CallContact
|
||||
import kotlinx.android.synthetic.main.activity_call.*
|
||||
import kotlinx.android.synthetic.main.dialpad.*
|
||||
|
||||
const val TAG = "SimpleDialer:CallManager"
|
||||
|
||||
class CallActivity : SimpleActivity() {
|
||||
companion object {
|
||||
fun getStartIntent(context: Context): Intent {
|
||||
val openAppIntent = Intent(context, CallActivity::class.java)
|
||||
openAppIntent.flags = Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT or Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
openAppIntent.flags = Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
|
||||
return openAppIntent
|
||||
}
|
||||
}
|
||||
@ -62,24 +62,21 @@ class CallActivity : SimpleActivity() {
|
||||
|
||||
audioManager.mode = AudioManager.MODE_IN_CALL
|
||||
|
||||
CallManager.getCallContact(applicationContext) { contact ->
|
||||
callContact = contact
|
||||
val avatar = callContactAvatarHelper.getCallContactAvatar(contact)
|
||||
runOnUiThread {
|
||||
updateOtherPersonsInfo(avatar)
|
||||
checkCalledSIMCard()
|
||||
}
|
||||
}
|
||||
|
||||
addLockScreenFlags()
|
||||
|
||||
CallManager.registerCallback(callCallback)
|
||||
updateCallState(CallManager.getState())
|
||||
CallManager.addListener(callCallback)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
updateCallState(CallManager.getPrimaryCall())
|
||||
updateCallOnHoldState(CallManager.getSecondaryCall())
|
||||
updateCallContactInfo(CallManager.getPrimaryCall())
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
CallManager.unregisterCallback(callCallback)
|
||||
CallManager.removeListener(callCallback)
|
||||
disableProximitySensor()
|
||||
}
|
||||
|
||||
@ -135,12 +132,23 @@ class CallActivity : SimpleActivity() {
|
||||
toggleHold()
|
||||
}
|
||||
|
||||
call_conference.setOnClickListener {
|
||||
/*if (is conference) {
|
||||
// show manage conference screen
|
||||
} else {
|
||||
// show dialpad and contacts
|
||||
}*/
|
||||
call_add.setOnClickListener {
|
||||
Intent(applicationContext, DialpadActivity::class.java).apply {
|
||||
addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
|
||||
startActivity(this)
|
||||
}
|
||||
}
|
||||
|
||||
call_swap.setOnClickListener {
|
||||
CallManager.swap()
|
||||
}
|
||||
|
||||
call_merge.setOnClickListener {
|
||||
CallManager.merge()
|
||||
}
|
||||
|
||||
call_manage.setOnClickListener {
|
||||
// TODO open conference participants list
|
||||
}
|
||||
|
||||
call_end.setOnClickListener {
|
||||
@ -347,6 +355,14 @@ class CallActivity : SimpleActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun getContactNameOrNumber(contact: CallContact): String {
|
||||
return contact.name.ifEmpty {
|
||||
contact.number.ifEmpty {
|
||||
getString(R.string.unknown_caller)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
private fun checkCalledSIMCard() {
|
||||
try {
|
||||
@ -375,7 +391,8 @@ class CallActivity : SimpleActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateCallState(state: Int) {
|
||||
private fun updateCallState(call: Call?) {
|
||||
val state = call?.getStateCompat()
|
||||
when (state) {
|
||||
Call.STATE_RINGING -> callRinging()
|
||||
Call.STATE_ACTIVE -> callStarted()
|
||||
@ -394,9 +411,35 @@ class CallActivity : SimpleActivity() {
|
||||
call_status_label.text = getString(statusTextId)
|
||||
}
|
||||
|
||||
val isActiveCall = state == Call.STATE_ACTIVE || state == Call.STATE_HOLDING
|
||||
call_toggle_hold.isEnabled = isActiveCall
|
||||
call_toggle_hold.alpha = if (isActiveCall) 1.0f else 0.5f
|
||||
val isSingleCallActionsEnabled = (state == Call.STATE_ACTIVE || state == Call.STATE_DISCONNECTED
|
||||
|| state == Call.STATE_DISCONNECTING || state == Call.STATE_HOLDING)
|
||||
setActionButtonEnabled(call_toggle_hold, isSingleCallActionsEnabled)
|
||||
setActionButtonEnabled(call_add, isSingleCallActionsEnabled)
|
||||
}
|
||||
|
||||
private fun updateCallOnHoldState(call: Call?) {
|
||||
val hasCallOnHold = call != null
|
||||
if (hasCallOnHold) {
|
||||
CallManager.getCallContact(applicationContext, call) { contact ->
|
||||
runOnUiThread {
|
||||
on_hold_caller_name.text = getContactNameOrNumber(contact)
|
||||
}
|
||||
}
|
||||
}
|
||||
on_hold_status_holder.beVisibleIf(hasCallOnHold)
|
||||
controls_single_call.beVisibleIf(!hasCallOnHold) // TODO and not conference
|
||||
controls_two_calls.beVisibleIf(hasCallOnHold)
|
||||
}
|
||||
|
||||
private fun updateCallContactInfo(call: Call?) {
|
||||
CallManager.getCallContact(applicationContext, call) { contact ->
|
||||
callContact = contact
|
||||
val avatar = callContactAvatarHelper.getCallContactAvatar(contact)
|
||||
runOnUiThread {
|
||||
updateOtherPersonsInfo(avatar)
|
||||
checkCalledSIMCard()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun acceptCall() {
|
||||
@ -417,6 +460,7 @@ class CallActivity : SimpleActivity() {
|
||||
enableProximitySensor()
|
||||
incoming_call_holder.beGone()
|
||||
ongoing_call_holder.beVisible()
|
||||
callDurationHandler.removeCallbacks(updateCallDurationTask)
|
||||
callDurationHandler.post(updateCallDurationTask)
|
||||
}
|
||||
|
||||
@ -456,10 +500,19 @@ class CallActivity : SimpleActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private val callCallback = object : Call.Callback() {
|
||||
private val callCallback = object : CallManagerListener {
|
||||
override fun onStateChanged(call: Call, state: Int) {
|
||||
super.onStateChanged(call, state)
|
||||
updateCallState(state)
|
||||
updateCallState(call)
|
||||
}
|
||||
|
||||
override fun onCallPutOnHold(call: Call?) {
|
||||
updateCallOnHoldState(call)
|
||||
}
|
||||
|
||||
override fun onCallsChanged(active: Call, onHold: Call?) {
|
||||
updateCallState(active)
|
||||
updateCallOnHoldState(onHold)
|
||||
updateCallContactInfo(active)
|
||||
}
|
||||
}
|
||||
|
||||
@ -507,4 +560,9 @@ class CallActivity : SimpleActivity() {
|
||||
proximityWakeLock!!.release()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setActionButtonEnabled(button: ImageView, isEnabled: Boolean) {
|
||||
button.isEnabled = isEnabled
|
||||
button.alpha = if (isEnabled) 1.0f else 0.4f
|
||||
}
|
||||
}
|
||||
|
@ -9,8 +9,10 @@ import com.simplemobiletools.commons.helpers.isSPlus
|
||||
private val OUTGOING_CALL_STATES = arrayOf(STATE_CONNECTING, STATE_DIALING, STATE_SELECT_PHONE_ACCOUNT)
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
fun Call.getStateCompat(): Int {
|
||||
return if (isSPlus()) {
|
||||
fun Call?.getStateCompat(): Int {
|
||||
return if (this == null) {
|
||||
Call.STATE_DISCONNECTED
|
||||
} else if (isSPlus()) {
|
||||
details.state
|
||||
} else {
|
||||
state
|
||||
@ -20,3 +22,9 @@ fun Call.getStateCompat(): Int {
|
||||
fun Call.isOutgoing(): Boolean {
|
||||
return OUTGOING_CALL_STATES.contains(getStateCompat())
|
||||
}
|
||||
|
||||
fun Call.hasCapability(capability: Int): Boolean = details.callCapabilities and capability != 0
|
||||
|
||||
fun Call.hasProperty(property: Int): Boolean = details.hasProperty(property)
|
||||
|
||||
fun Call?.isConference(): Boolean = this?.details?.hasProperty(Call.Details.PROPERTY_CONFERENCE) == true
|
||||
|
@ -5,6 +5,7 @@ import android.net.Uri
|
||||
import android.telecom.Call
|
||||
import android.telecom.InCallService
|
||||
import android.telecom.VideoProfile
|
||||
import android.util.Log
|
||||
import com.simplemobiletools.commons.extensions.getMyContactsCursor
|
||||
import com.simplemobiletools.commons.extensions.getPhoneNumberTypeText
|
||||
import com.simplemobiletools.commons.helpers.MyContactsContentProvider
|
||||
@ -12,12 +13,64 @@ import com.simplemobiletools.commons.helpers.SimpleContactsHelper
|
||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||
import com.simplemobiletools.dialer.extensions.getStateCompat
|
||||
import com.simplemobiletools.dialer.models.CallContact
|
||||
import java.util.concurrent.CopyOnWriteArraySet
|
||||
|
||||
const val TAG = "SimpleDialer:CallManager"
|
||||
|
||||
// inspired by https://github.com/Chooloo/call_manage
|
||||
class CallManager {
|
||||
companion object {
|
||||
var call: Call? = null
|
||||
var inCallService: InCallService? = null
|
||||
val calls = mutableListOf<Call>()
|
||||
private val listeners = CopyOnWriteArraySet<CallManagerListener>()
|
||||
|
||||
fun onCallAdded(call: Call) {
|
||||
this.call = call
|
||||
calls.add(call)
|
||||
call.registerCallback(object : Call.Callback() {
|
||||
override fun onStateChanged(call: Call, state: Int) {
|
||||
Log.d(TAG, "onStateChanged: $call")
|
||||
for (listener in listeners) {
|
||||
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())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun onCallRemoved(call: Call) {
|
||||
calls.remove(call)
|
||||
}
|
||||
|
||||
fun getPrimaryCall(): Call? {
|
||||
return call
|
||||
}
|
||||
|
||||
fun getSecondaryCall(): Call? {
|
||||
if (calls.size == 1) {
|
||||
return null
|
||||
}
|
||||
return calls.find { it.getStateCompat() == Call.STATE_HOLDING }
|
||||
}
|
||||
|
||||
fun accept() {
|
||||
call?.answer(VideoProfile.STATE_AUDIO_ONLY)
|
||||
@ -43,27 +96,33 @@ class CallManager {
|
||||
return !isOnHold
|
||||
}
|
||||
|
||||
fun swap() {
|
||||
val isConference: Boolean
|
||||
get() = call?.details?.hasProperty(Call.Details.PROPERTY_CONFERENCE) ?: false
|
||||
|
||||
fun swap() {
|
||||
getSecondaryCall()?.unhold()
|
||||
}
|
||||
|
||||
fun merge() {
|
||||
|
||||
// val conferenceableCalls = call!!.conferenceableCalls
|
||||
// if (conferenceableCalls.isNotEmpty()) {
|
||||
// call!!.conference(conferenceableCalls.first())
|
||||
// } else {
|
||||
// if (call!!.hasCapability(Call.Details.CAPABILITY_MERGE_CONFERENCE)) {
|
||||
// call!!.mergeConference()
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
fun registerCallback(callback: Call.Callback) {
|
||||
call?.registerCallback(callback)
|
||||
fun addListener(listener: CallManagerListener) {
|
||||
listeners.add(listener)
|
||||
}
|
||||
|
||||
fun unregisterCallback(callback: Call.Callback) {
|
||||
call?.unregisterCallback(callback)
|
||||
fun removeListener(listener: CallManagerListener) {
|
||||
listeners.remove(listener)
|
||||
}
|
||||
|
||||
fun getState() = if (call == null) {
|
||||
Call.STATE_DISCONNECTED
|
||||
} else {
|
||||
call!!.getStateCompat()
|
||||
}
|
||||
fun getState() = getPrimaryCall()?.getStateCompat()
|
||||
|
||||
fun keypad(c: Char) {
|
||||
call?.playDtmfTone(c)
|
||||
@ -71,6 +130,10 @@ class CallManager {
|
||||
}
|
||||
|
||||
fun getCallContact(context: Context, callback: (CallContact?) -> Unit) {
|
||||
return getCallContact(context, call, callback)
|
||||
}
|
||||
|
||||
fun getCallContact(context: Context, call: Call?, callback: (CallContact) -> Unit) {
|
||||
val privateCursor = context.getMyContactsCursor(false, true)
|
||||
ensureBackgroundThread {
|
||||
val callContact = CallContact("", "", "", "")
|
||||
@ -126,10 +189,20 @@ class CallManager {
|
||||
|
||||
fun getCallDuration(): Int {
|
||||
return if (call != null) {
|
||||
((System.currentTimeMillis() - call!!.details.connectTimeMillis) / 1000).toInt()
|
||||
val connectTimeMillis = call!!.details.connectTimeMillis
|
||||
if (connectTimeMillis == 0L) {
|
||||
return 0
|
||||
}
|
||||
((System.currentTimeMillis() - connectTimeMillis) / 1000).toInt()
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface CallManagerListener {
|
||||
fun onStateChanged(call: Call, state: Int)
|
||||
fun onCallPutOnHold(call: Call?)
|
||||
fun onCallsChanged(active: Call, onHold: Call?)
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ class CallService : InCallService() {
|
||||
private val callListener = object : Call.Callback() {
|
||||
override fun onStateChanged(call: Call, state: Int) {
|
||||
super.onStateChanged(call, state)
|
||||
Log.d(TAG, "onStateChanged: $call")
|
||||
if (state != Call.STATE_DISCONNECTED) {
|
||||
callNotificationManager.setupNotification()
|
||||
}
|
||||
@ -27,26 +26,36 @@ class CallService : InCallService() {
|
||||
override fun onCallAdded(call: Call) {
|
||||
super.onCallAdded(call)
|
||||
Log.d(TAG, "onCallAdded: $call")
|
||||
if (!powerManager.isInteractive || call.isOutgoing()) {
|
||||
CallManager.onCallAdded(call)
|
||||
if ((!powerManager.isInteractive || call.isOutgoing())) {
|
||||
startActivity(CallActivity.getStartIntent(this))
|
||||
}
|
||||
CallManager.call = call
|
||||
call.registerCallback(callListener)
|
||||
CallManager.inCallService = this
|
||||
CallManager.registerCallback(callListener)
|
||||
callNotificationManager.setupNotification()
|
||||
Log.d(TAG, "onCallAdded: calls=${CallManager.calls.size}")
|
||||
}
|
||||
|
||||
override fun onCallRemoved(call: Call) {
|
||||
super.onCallRemoved(call)
|
||||
Log.d(TAG, "onCallRemoved: $call")
|
||||
CallManager.call = null
|
||||
CallManager.inCallService = null
|
||||
callNotificationManager.cancelNotification()
|
||||
call.unregisterCallback(callListener)
|
||||
CallManager.onCallRemoved(call)
|
||||
if (CallManager.calls.isEmpty()) {
|
||||
CallManager.call = null
|
||||
CallManager.inCallService = null
|
||||
callNotificationManager.cancelNotification()
|
||||
} else {
|
||||
// TODO if left more than 1
|
||||
CallManager.call = CallManager.calls.first()
|
||||
callNotificationManager.setupNotification()
|
||||
startActivity(CallActivity.getStartIntent(this))
|
||||
}
|
||||
Log.d(TAG, "onCallRemoved: calls=${CallManager.calls.size}")
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
CallManager.unregisterCallback(callListener)
|
||||
callNotificationManager.cancelNotification()
|
||||
}
|
||||
}
|
||||
|
@ -102,6 +102,54 @@
|
||||
app:layout_constraintTop_toTopOf="@+id/call_sim_image"
|
||||
tools:text="1" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/on_hold_status_holder"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/cardview_shadow_start_color"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/normal_margin"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_phone_vector" />
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/on_hold_caller_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/normal_margin"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textSize="@dimen/call_status_text_size"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/on_hold_label"
|
||||
app:layout_constraintStart_toEndOf="@+id/imageView"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="0912 345 678" />
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/on_hold_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/normal_margin"
|
||||
android:text="@string/call_on_hold"
|
||||
android:textSize="@dimen/call_status_text_size"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/imageView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/imageView" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/ongoing_call_holder"
|
||||
android:layout_width="match_parent"
|
||||
@ -157,24 +205,24 @@
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:padding="@dimen/medium_margin"
|
||||
android:src="@drawable/ic_pause_inset"
|
||||
app:layout_constraintEnd_toStartOf="@id/call_conference"
|
||||
app:layout_constraintEnd_toStartOf="@id/call_add"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/call_toggle_speaker" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/call_conference"
|
||||
android:id="@+id/call_add"
|
||||
android:layout_width="@dimen/dialpad_button_size"
|
||||
android:layout_height="@dimen/dialpad_button_size"
|
||||
android:layout_marginTop="@dimen/bigger_margin"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:padding="@dimen/medium_margin"
|
||||
android:src="@drawable/ic_add_call_vector"
|
||||
app:layout_constraintEnd_toStartOf="@id/manage_conference"
|
||||
app:layout_constraintEnd_toEndOf="@id/call_manage"
|
||||
app:layout_constraintStart_toEndOf="@+id/call_toggle_hold"
|
||||
app:layout_constraintTop_toBottomOf="@+id/call_toggle_speaker" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/manage_conference"
|
||||
android:id="@+id/call_manage"
|
||||
android:layout_width="@dimen/dialpad_button_size"
|
||||
android:layout_height="@dimen/dialpad_button_size"
|
||||
android:layout_marginTop="@dimen/bigger_margin"
|
||||
@ -183,9 +231,35 @@
|
||||
android:src="@drawable/ic_people_vector"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/call_conference"
|
||||
app:layout_constraintTop_toBottomOf="@+id/call_toggle_speaker"
|
||||
tools:visibility="visible" />
|
||||
app:layout_constraintStart_toEndOf="@+id/call_add"
|
||||
app:layout_constraintTop_toBottomOf="@+id/call_toggle_speaker" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/call_swap"
|
||||
android:layout_width="@dimen/dialpad_button_size"
|
||||
android:layout_height="@dimen/dialpad_button_size"
|
||||
android:layout_marginTop="@dimen/bigger_margin"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:padding="@dimen/medium_margin"
|
||||
android:src="@drawable/ic_call_swap_vector"
|
||||
app:layout_constraintEnd_toStartOf="@+id/call_merge"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toEndOf="@+id/call_add"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/call_toggle_speaker" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/call_merge"
|
||||
android:layout_width="@dimen/dialpad_button_size"
|
||||
android:layout_height="@dimen/dialpad_button_size"
|
||||
android:layout_marginTop="@dimen/bigger_margin"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:padding="@dimen/medium_margin"
|
||||
android:src="@drawable/ic_call_merge_vector"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toEndOf="@+id/call_swap"
|
||||
app:layout_constraintTop_toBottomOf="@+id/call_toggle_speaker" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/call_end"
|
||||
@ -199,6 +273,21 @@
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.9" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/controls_single_call"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
app:constraint_referenced_ids="call_toggle_hold,call_add"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/controls_two_calls"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
app:constraint_referenced_ids="call_swap,call_merge" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
|
Loading…
x
Reference in New Issue
Block a user