feat: updating call layout
This commit is contained in:
parent
3d0e5541d0
commit
b6c53b4964
|
@ -54,7 +54,6 @@
|
|||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" tools:node="remove"/>
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||
<uses-permission android:name="android.permission.CALL_PHONE" />
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
|
|
|
@ -5,11 +5,14 @@ import android.content.BroadcastReceiver
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.media.AudioManager
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import androidx.activity.viewModels
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
|
@ -65,6 +68,14 @@ class WebRtcCallActivity: PassphraseRequiredActionBarActivity() {
|
|||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
super.onNewIntent(intent)
|
||||
if (intent?.action == ACTION_ANSWER) {
|
||||
val answerIntent = WebRtcCallService.acceptCallIntent(this)
|
||||
ContextCompat.startForegroundService(this,answerIntent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) {
|
||||
super.onCreate(savedInstanceState, ready)
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED)
|
||||
|
@ -82,9 +93,18 @@ class WebRtcCallActivity: PassphraseRequiredActionBarActivity() {
|
|||
.execute()
|
||||
|
||||
if (intent.action == ACTION_ANSWER) {
|
||||
// answer via ViewModel
|
||||
val answerIntent = WebRtcCallService.acceptCallIntent(this)
|
||||
startService(answerIntent)
|
||||
ContextCompat.startForegroundService(this,answerIntent)
|
||||
}
|
||||
|
||||
acceptCallButton.setOnClickListener {
|
||||
val answerIntent = WebRtcCallService.acceptCallIntent(this)
|
||||
ContextCompat.startForegroundService(this,answerIntent)
|
||||
}
|
||||
|
||||
declineCallButton.setOnClickListener {
|
||||
val declineIntent = WebRtcCallService.hangupIntent(this)
|
||||
startService(declineIntent)
|
||||
}
|
||||
|
||||
registerReceiver(object: BroadcastReceiver() {
|
||||
|
@ -128,7 +148,20 @@ class WebRtcCallActivity: PassphraseRequiredActionBarActivity() {
|
|||
|
||||
launch {
|
||||
viewModel.callState.collect { state ->
|
||||
remote_loading_view.isVisible = state != CALL_CONNECTED
|
||||
when (state) {
|
||||
CALL_RINGING -> {
|
||||
|
||||
}
|
||||
CALL_OUTGOING -> {
|
||||
|
||||
}
|
||||
CALL_CONNECTED -> {
|
||||
|
||||
}
|
||||
}
|
||||
controlGroup.isVisible = state in listOf(CALL_CONNECTED, CALL_OUTGOING, CALL_INCOMING)
|
||||
remote_loading_view.isVisible = state !in listOf(CALL_CONNECTED, CALL_RINGING)
|
||||
incomingControlGroup.isVisible = state == CALL_RINGING
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,9 +198,10 @@ class WebRtcCallActivity: PassphraseRequiredActionBarActivity() {
|
|||
}
|
||||
local_renderer.isVisible = isEnabled
|
||||
enableCameraButton.setImageResource(
|
||||
if (isEnabled) R.drawable.ic_baseline_videocam_off_24
|
||||
else R.drawable.ic_baseline_videocam_24
|
||||
if (isEnabled) R.drawable.ic_outline_videocam_off_24
|
||||
else R.drawable.ic_outline_videocam_24
|
||||
)
|
||||
enableCameraButton.styleEnabled(isEnabled)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,7 +218,15 @@ class WebRtcCallActivity: PassphraseRequiredActionBarActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
fun getUserDisplayName(publicKey: String): String {
|
||||
fun View.styleEnabled(isEnabled: Boolean) {
|
||||
if (isEnabled) {
|
||||
setBackgroundResource(R.drawable.call_controls_selected)
|
||||
} else {
|
||||
setBackgroundResource(R.drawable.call_controls_unselected)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getUserDisplayName(publicKey: String): String {
|
||||
val contact = DatabaseComponent.get(this).sessionContactDatabase().getContactWithSessionID(publicKey)
|
||||
return contact?.displayName(Contact.ContactContext.REGULAR) ?: publicKey
|
||||
}
|
||||
|
|
|
@ -337,23 +337,23 @@ class WebRtcCallService: Service(), PeerConnection.Observer {
|
|||
val recipient = callManager.recipient ?: return
|
||||
val timestamp = callManager.pendingOfferTime
|
||||
|
||||
setCallInProgressNotification(TYPE_INCOMING_CONNECTING, recipient)
|
||||
|
||||
intent.putExtra(EXTRA_CALL_ID, callId)
|
||||
intent.putExtra(EXTRA_RECIPIENT_ADDRESS, recipient.address)
|
||||
intent.putExtra(EXTRA_REMOTE_DESCRIPTION, pending)
|
||||
intent.putExtra(EXTRA_TIMESTAMP, timestamp)
|
||||
|
||||
callManager.postConnectionEvent(STATE_ANSWERING)
|
||||
callManager.postViewModelState(CallViewModel.State.CALL_INCOMING)
|
||||
|
||||
if (isIncomingMessageExpired(intent)) {
|
||||
insertMissedCall(recipient, true)
|
||||
terminate()
|
||||
return
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
setCallInProgressNotification(TYPE_INCOMING_CONNECTING, recipient)
|
||||
}
|
||||
|
||||
timeoutExecutor.schedule(TimeoutRunnable(callId, this), 5, TimeUnit.MINUTES)
|
||||
timeoutExecutor.schedule(TimeoutRunnable(callId, this), 2, TimeUnit.MINUTES)
|
||||
|
||||
callManager.initializeAudioForCall()
|
||||
callManager.initializeVideo(this)
|
||||
|
@ -370,7 +370,6 @@ class WebRtcCallService: Service(), PeerConnection.Observer {
|
|||
terminate()
|
||||
}
|
||||
}
|
||||
callManager.postViewModelState(CallViewModel.State.CALL_INCOMING)
|
||||
lockManager.updatePhoneState(LockManager.PhoneState.PROCESSING)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG,e)
|
||||
|
|
|
@ -46,6 +46,7 @@ class CallNotificationBuilder {
|
|||
}
|
||||
TYPE_INCOMING_RINGING -> {
|
||||
builder.setContentText(context.getString(R.string.NotificationBarManager__incoming_signal_call))
|
||||
.setCategory(NotificationCompat.CATEGORY_CALL)
|
||||
builder.addAction(getServiceNotificationAction(
|
||||
context,
|
||||
WebRtcCallService.ACTION_DENY_CALL,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.thoughtcrime.securesms.webrtc.audio
|
||||
|
||||
import android.Manifest
|
||||
import android.bluetooth.BluetoothAdapter
|
||||
import android.bluetooth.BluetoothDevice
|
||||
import android.bluetooth.BluetoothHeadset
|
||||
|
@ -32,8 +33,6 @@ class SignalBluetoothManager(
|
|||
}
|
||||
private set
|
||||
|
||||
private fun hasPermission() = false
|
||||
|
||||
private var bluetoothAdapter: BluetoothAdapter? = null
|
||||
private var bluetoothDevice: BluetoothDevice? = null
|
||||
private var bluetoothHeadset: BluetoothHeadset? = null
|
||||
|
@ -92,7 +91,7 @@ class SignalBluetoothManager(
|
|||
|
||||
Log.d(TAG, "stop(): state: $state")
|
||||
|
||||
if (bluetoothAdapter == null || !hasPermission()) {
|
||||
if (bluetoothAdapter == null) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -125,7 +124,6 @@ class SignalBluetoothManager(
|
|||
|
||||
fun startScoAudio(): Boolean {
|
||||
handler.assertHandlerThread()
|
||||
if (!hasPermission()) return false
|
||||
|
||||
Log.i(TAG, "startScoAudio(): $state attempts: $scoConnectionAttempts")
|
||||
|
||||
|
@ -150,7 +148,6 @@ class SignalBluetoothManager(
|
|||
|
||||
fun stopScoAudio() {
|
||||
handler.assertHandlerThread()
|
||||
if (!hasPermission()) return
|
||||
|
||||
Log.i(TAG, "stopScoAudio(): $state")
|
||||
|
||||
|
@ -166,7 +163,6 @@ class SignalBluetoothManager(
|
|||
|
||||
fun updateDevice() {
|
||||
handler.assertHandlerThread()
|
||||
if (!hasPermission()) return
|
||||
|
||||
Log.d(TAG, "updateDevice(): state: $state")
|
||||
|
||||
|
@ -200,7 +196,6 @@ class SignalBluetoothManager(
|
|||
|
||||
private fun onBluetoothTimeout() {
|
||||
Log.i(TAG, "onBluetoothTimeout: state: $state bluetoothHeadset: $bluetoothHeadset")
|
||||
if (!hasPermission()) return
|
||||
|
||||
if (state == State.UNINITIALIZED || bluetoothHeadset == null || state != State.CONNECTING) {
|
||||
return
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape android:shape="oval"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@color/unimportant"/>
|
||||
</shape>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape android:shape="oval"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<stroke android:color="@color/unimportant" android:width="@dimen/small_spacing"/>
|
||||
</shape>
|
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M15,8v8H5V8h10m1,-2H4c-0.55,0 -1,0.45 -1,1v10c0,0.55 0.45,1 1,1h12c0.55,0 1,-0.45 1,-1v-3.5l4,4v-11l-4,4V7c0,-0.55 -0.45,-1 -1,-1z"/>
|
||||
</vector>
|
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M9.56,8l-2,-2 -4.15,-4.14L2,3.27 4.73,6L4,6c-0.55,0 -1,0.45 -1,1v10c0,0.55 0.45,1 1,1h12c0.21,0 0.39,-0.08 0.55,-0.18L19.73,21l1.41,-1.41 -8.86,-8.86L9.56,8zM5,16L5,8h1.73l8,8L5,16zM15,8v2.61l6,6L21,6.5l-4,4L17,7c0,-0.55 -0.45,-1 -1,-1h-5.61l2,2L15,8z"/>
|
||||
</vector>
|
|
@ -7,29 +7,39 @@
|
|||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/remote_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/remote_renderer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
<com.github.ybq.android.spinkit.SpinKitView
|
||||
android:id="@+id/remote_loading_view"
|
||||
style="@style/SpinKitView.Large.ThreeBounce"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:SpinKit_Color="@color/text"
|
||||
android:layout_gravity="center"
|
||||
tools:visibility="visible"
|
||||
android:visibility="gone" />
|
||||
<com.makeramen.roundedimageview.RoundedImageView
|
||||
android:id="@+id/remote_recipient"
|
||||
android:layout_gravity="center"
|
||||
android:layout_width="@dimen/extra_large_profile_picture_size"
|
||||
android:layout_height="@dimen/extra_large_profile_picture_size"/>
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</FrameLayout>
|
||||
<com.makeramen.roundedimageview.RoundedImageView
|
||||
android:id="@+id/remote_recipient"
|
||||
app:layout_constraintStart_toStartOf="@id/remote_parent"
|
||||
app:layout_constraintEnd_toEndOf="@id/remote_parent"
|
||||
app:layout_constraintTop_toTopOf="@id/remote_parent"
|
||||
app:layout_constraintBottom_toBottomOf="@id/remote_parent"
|
||||
android:layout_width="@dimen/extra_large_profile_picture_size"
|
||||
android:layout_height="@dimen/extra_large_profile_picture_size"/>
|
||||
|
||||
<com.github.ybq.android.spinkit.SpinKitView
|
||||
android:id="@+id/remote_loading_view"
|
||||
style="@style/SpinKitView.ThreeBounce"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:foregroundGravity="center"
|
||||
android:visibility="gone"
|
||||
app:SpinKit_Color="@color/text"
|
||||
app:layout_constraintEnd_toEndOf="@+id/remote_recipient"
|
||||
app:layout_constraintStart_toStartOf="@+id/remote_recipient"
|
||||
app:layout_constraintTop_toBottomOf="@id/remote_recipient"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<FrameLayout
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
@ -59,7 +69,7 @@
|
|||
android:id="@+id/endCallButton"
|
||||
android:background="@drawable/circle_tintable"
|
||||
android:src="@drawable/ic_baseline_call_end_24"
|
||||
android:padding="@dimen/small_spacing"
|
||||
android:padding="@dimen/medium_spacing"
|
||||
app:tint="@color/core_white"
|
||||
android:backgroundTint="@color/destructive"
|
||||
android:layout_width="@dimen/large_button_height"
|
||||
|
@ -74,12 +84,12 @@
|
|||
android:id="@+id/switchCameraButton"
|
||||
android:background="@drawable/circle_tintable"
|
||||
android:src="@drawable/ic_baseline_flip_camera_android_24"
|
||||
android:padding="@dimen/small_spacing"
|
||||
android:padding="@dimen/medium_spacing"
|
||||
app:tint="@color/unimportant"
|
||||
android:backgroundTint="@color/unimportant_button_background"
|
||||
android:layout_width="@dimen/large_button_height"
|
||||
android:layout_height="@dimen/large_button_height"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@+id/endCallButton"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_marginBottom="@dimen/large_spacing"
|
||||
|
@ -90,44 +100,87 @@
|
|||
android:id="@+id/enableCameraButton"
|
||||
android:background="@drawable/circle_tintable"
|
||||
android:src="@drawable/ic_baseline_videocam_24"
|
||||
android:padding="@dimen/small_spacing"
|
||||
android:padding="@dimen/medium_spacing"
|
||||
app:tint="@color/unimportant"
|
||||
android:backgroundTint="@color/unimportant_button_background"
|
||||
android:layout_width="@dimen/large_button_height"
|
||||
android:layout_height="@dimen/large_button_height"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@+id/endCallButton"
|
||||
app:layout_constraintStart_toEndOf="@id/switchCameraButton"
|
||||
app:layout_constraintEnd_toStartOf="@id/endCallButton"
|
||||
app:layout_constraintEnd_toStartOf="@id/microphoneButton"
|
||||
android:layout_marginBottom="@dimen/large_spacing"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/microphoneButton"
|
||||
android:layout_width="@dimen/large_button_height"
|
||||
android:layout_height="@dimen/large_button_height"
|
||||
android:padding="@dimen/small_spacing"
|
||||
android:padding="@dimen/medium_spacing"
|
||||
android:src="@drawable/ic_microphone"
|
||||
app:tint="@color/unimportant"
|
||||
android:layout_marginBottom="@dimen/large_spacing"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@+id/endCallButton"
|
||||
android:backgroundTint="@color/unimportant_button_background"
|
||||
android:background="@drawable/circle_tintable"
|
||||
app:layout_constraintEnd_toStartOf="@id/speakerPhoneButton"
|
||||
app:layout_constraintStart_toEndOf="@id/endCallButton"/>
|
||||
app:layout_constraintStart_toEndOf="@id/enableCameraButton"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/speakerPhoneButton"
|
||||
android:background="@drawable/circle_tintable"
|
||||
android:src="@drawable/ic_audio_light"
|
||||
android:padding="@dimen/small_spacing"
|
||||
android:padding="@dimen/medium_spacing"
|
||||
app:tint="@color/unimportant"
|
||||
android:backgroundTint="@color/unimportant_button_background"
|
||||
android:layout_width="@dimen/large_button_height"
|
||||
android:layout_height="@dimen/large_button_height"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@+id/endCallButton"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_marginBottom="@dimen/large_spacing"
|
||||
app:layout_constraintHorizontal_bias="0.9"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:textAllCaps="true"
|
||||
style="@style/Widget.Session.Button.Common.ProminentOutline"
|
||||
android:text="@string/accept_call"
|
||||
android:layout_marginBottom="@dimen/large_spacing"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.85"
|
||||
android:padding="@dimen/medium_spacing"
|
||||
android:gravity="center"
|
||||
android:id="@+id/acceptCallButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:textAllCaps="true"
|
||||
style="@style/Widget.Session.Button.Common.UnimportantDestructive"
|
||||
android:text="@string/decline_call"
|
||||
android:layout_marginBottom="@dimen/large_spacing"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.15"
|
||||
android:padding="@dimen/medium_spacing"
|
||||
android:id="@+id/declineCallButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/controlGroup"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:constraint_referenced_ids="enableCameraButton,endCallButton,switchCameraButton,speakerPhoneButton,microphoneButton"
|
||||
/>
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:id="@+id/incomingControlGroup"
|
||||
app:constraint_referenced_ids="acceptCallButton,declineCallButton"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -911,5 +911,7 @@
|
|||
<string name="NotificationBarManager__cancel_call">Cancel call</string>
|
||||
<string name="NotificationBarManager__establishing_signal_call">Establishing call</string>
|
||||
<string name="NotificationBarManager__end_call">End call</string>
|
||||
<string name="accept_call">Accept Call</string>
|
||||
<string name="decline_call">Decline call</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -95,6 +95,13 @@
|
|||
<item name="android:drawableTint" tools:ignore="NewApi">?android:textColorPrimary</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Session.Button.Common.UnimportantDestructive">
|
||||
<item name="android:background">@drawable/unimportant_outline_button_medium_background</item>
|
||||
<item name="android:textColor">@color/destructive</item>
|
||||
<item name="android:backgroundTint" tools:ignore="NewApi">@color/destructive</item>
|
||||
<item name="android:drawableTint" tools:ignore="NewApi">@color/destructive</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Session.Button.Dialog" parent="">
|
||||
<item name="android:textAllCaps">false</item>
|
||||
<item name="android:textSize">@dimen/small_font_size</item>
|
||||
|
|
Loading…
Reference in New Issue