refactor: compile errors and refactoring to view binding
This commit is contained in:
parent
38164ea23d
commit
53127b69de
|
@ -17,6 +17,7 @@ apply plugin: 'com.android.application'
|
|||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'witness'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
apply plugin: 'kotlin-parcelize'
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
apply plugin: 'kotlinx-serialization'
|
||||
apply plugin: 'dagger.hilt.android.plugin'
|
||||
|
@ -157,7 +158,7 @@ dependencies {
|
|||
testImplementation 'org.robolectric:shadows-multidex:4.4'
|
||||
}
|
||||
|
||||
def canonicalVersionCode = 249
|
||||
def canonicalVersionCode = 250
|
||||
def canonicalVersionName = "1.12.2"
|
||||
|
||||
def postFixSize = 10
|
||||
|
|
|
@ -134,6 +134,7 @@ public class ApplicationContext extends Application implements DefaultLifecycleO
|
|||
@Inject Storage storage;
|
||||
@Inject MessageDataProvider messageDataProvider;
|
||||
@Inject JobDatabase jobDatabase;
|
||||
@Inject TextSecurePreferences textSecurePreferences;
|
||||
CallMessageProcessor callMessageProcessor;
|
||||
|
||||
private volatile boolean isAppVisible;
|
||||
|
@ -161,7 +162,7 @@ public class ApplicationContext extends Application implements DefaultLifecycleO
|
|||
public void onCreate() {
|
||||
DatabaseModule.init(this);
|
||||
super.onCreate();
|
||||
callMessageProcessor = new CallMessageProcessor(this, ProcessLifecycleOwner.get().getLifecycle(), storage);
|
||||
callMessageProcessor = new CallMessageProcessor(this, textSecurePreferences, ProcessLifecycleOwner.get().getLifecycle(), storage);
|
||||
Log.i(TAG, "onCreate()");
|
||||
startKovenant();
|
||||
initializeSecurityProvider();
|
||||
|
|
|
@ -9,20 +9,19 @@ import android.media.AudioManager
|
|||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.*
|
||||
import android.widget.FrameLayout
|
||||
import androidx.activity.viewModels
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.contains
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.android.synthetic.main.activity_conversation_v2.*
|
||||
import kotlinx.android.synthetic.main.activity_webrtc.*
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import network.loki.messenger.R
|
||||
import network.loki.messenger.databinding.ActivityWebrtcBinding
|
||||
import org.apache.commons.lang3.time.DurationFormatUtils
|
||||
import org.session.libsession.avatars.ProfileContactPhoto
|
||||
import org.session.libsession.messaging.contacts.Contact
|
||||
|
@ -36,11 +35,10 @@ import org.thoughtcrime.securesms.webrtc.AudioManagerCommand
|
|||
import org.thoughtcrime.securesms.webrtc.CallViewModel
|
||||
import org.thoughtcrime.securesms.webrtc.CallViewModel.State.*
|
||||
import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager.AudioDevice.*
|
||||
import org.webrtc.RendererCommon
|
||||
import java.util.*
|
||||
|
||||
@AndroidEntryPoint
|
||||
class WebRtcCallActivity: PassphraseRequiredActionBarActivity() {
|
||||
class WebRtcCallActivity : PassphraseRequiredActionBarActivity() {
|
||||
|
||||
companion object {
|
||||
const val ACTION_PRE_OFFER = "pre-offer"
|
||||
|
@ -55,6 +53,7 @@ class WebRtcCallActivity: PassphraseRequiredActionBarActivity() {
|
|||
|
||||
private val viewModel by viewModels<CallViewModel>()
|
||||
private val glide by lazy { GlideApp.with(this) }
|
||||
private lateinit var binding: ActivityWebrtcBinding
|
||||
private var uiJob: Job? = null
|
||||
private var wantsToAnswer = false
|
||||
set(value) {
|
||||
|
@ -75,23 +74,24 @@ class WebRtcCallActivity: PassphraseRequiredActionBarActivity() {
|
|||
super.onNewIntent(intent)
|
||||
if (intent?.action == ACTION_ANSWER) {
|
||||
val answerIntent = WebRtcCallService.acceptCallIntent(this)
|
||||
ContextCompat.startForegroundService(this,answerIntent)
|
||||
ContextCompat.startForegroundService(this, answerIntent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) {
|
||||
super.onCreate(savedInstanceState, ready)
|
||||
setContentView(R.layout.activity_webrtc)
|
||||
binding = ActivityWebrtcBinding.inflate(layoutInflater)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
||||
setShowWhenLocked(true)
|
||||
setTurnScreenOn(true)
|
||||
}
|
||||
window.addFlags(
|
||||
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
|
||||
or WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
|
||||
or WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
|
||||
or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
|
||||
or WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON)
|
||||
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
|
||||
or WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
|
||||
or WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
|
||||
or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
|
||||
or WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
|
||||
)
|
||||
volumeControlStream = AudioManager.STREAM_VOICE_CALL
|
||||
|
||||
if (intent.action == ACTION_ANSWER) {
|
||||
|
@ -105,17 +105,19 @@ class WebRtcCallActivity: PassphraseRequiredActionBarActivity() {
|
|||
supportActionBar?.setDisplayHomeAsUpEnabled(false)
|
||||
}
|
||||
|
||||
microphoneButton.setOnClickListener {
|
||||
val audioEnabledIntent = WebRtcCallService.microphoneIntent(this, !viewModel.microphoneEnabled)
|
||||
binding.microphoneButton.setOnClickListener {
|
||||
val audioEnabledIntent =
|
||||
WebRtcCallService.microphoneIntent(this, !viewModel.microphoneEnabled)
|
||||
startService(audioEnabledIntent)
|
||||
}
|
||||
|
||||
speakerPhoneButton.setOnClickListener {
|
||||
val command = AudioManagerCommand.SetUserDevice( if (viewModel.isSpeaker) EARPIECE else SPEAKER_PHONE)
|
||||
binding.speakerPhoneButton.setOnClickListener {
|
||||
val command =
|
||||
AudioManagerCommand.SetUserDevice(if (viewModel.isSpeaker) EARPIECE else SPEAKER_PHONE)
|
||||
WebRtcCallService.sendAudioManagerCommand(this, command)
|
||||
}
|
||||
|
||||
acceptCallButton.setOnClickListener {
|
||||
binding.acceptCallButton.setOnClickListener {
|
||||
if (viewModel.currentCallState == CALL_PRE_INIT) {
|
||||
wantsToAnswer = true
|
||||
updateControls()
|
||||
|
@ -123,34 +125,35 @@ class WebRtcCallActivity: PassphraseRequiredActionBarActivity() {
|
|||
answerCall()
|
||||
}
|
||||
|
||||
declineCallButton.setOnClickListener {
|
||||
binding.declineCallButton.setOnClickListener {
|
||||
val declineIntent = WebRtcCallService.denyCallIntent(this)
|
||||
startService(declineIntent)
|
||||
}
|
||||
|
||||
hangupReceiver = object: BroadcastReceiver() {
|
||||
hangupReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
LocalBroadcastManager.getInstance(this).registerReceiver(hangupReceiver!!,IntentFilter(ACTION_END))
|
||||
LocalBroadcastManager.getInstance(this)
|
||||
.registerReceiver(hangupReceiver!!, IntentFilter(ACTION_END))
|
||||
|
||||
enableCameraButton.setOnClickListener {
|
||||
binding.enableCameraButton.setOnClickListener {
|
||||
Permissions.with(this)
|
||||
.request(Manifest.permission.CAMERA)
|
||||
.onAllGranted {
|
||||
val intent = WebRtcCallService.cameraEnabled(this, !viewModel.videoEnabled)
|
||||
startService(intent)
|
||||
}
|
||||
.execute()
|
||||
.request(Manifest.permission.CAMERA)
|
||||
.onAllGranted {
|
||||
val intent = WebRtcCallService.cameraEnabled(this, !viewModel.videoEnabled)
|
||||
startService(intent)
|
||||
}
|
||||
.execute()
|
||||
}
|
||||
|
||||
switchCameraButton.setOnClickListener {
|
||||
binding.switchCameraButton.setOnClickListener {
|
||||
startService(WebRtcCallService.flipCamera(this))
|
||||
}
|
||||
|
||||
endCallButton.setOnClickListener {
|
||||
binding.endCallButton.setOnClickListener {
|
||||
startService(WebRtcCallService.hangupIntent(this))
|
||||
}
|
||||
|
||||
|
@ -165,20 +168,29 @@ class WebRtcCallActivity: PassphraseRequiredActionBarActivity() {
|
|||
|
||||
private fun answerCall() {
|
||||
val answerIntent = WebRtcCallService.acceptCallIntent(this)
|
||||
ContextCompat.startForegroundService(this,answerIntent)
|
||||
ContextCompat.startForegroundService(this, answerIntent)
|
||||
}
|
||||
|
||||
private fun updateControls(state: CallViewModel.State? = null) {
|
||||
if (state == null) {
|
||||
if (wantsToAnswer) {
|
||||
controlGroup.isVisible = true
|
||||
remote_loading_view.isVisible = true
|
||||
incomingControlGroup.isVisible = false
|
||||
with (binding) {
|
||||
if (state == null) {
|
||||
if (wantsToAnswer) {
|
||||
controlGroup.isVisible = true
|
||||
remoteLoadingView.isVisible = true
|
||||
incomingControlGroup.isVisible = false
|
||||
}
|
||||
} else {
|
||||
|
||||
controlGroup.isVisible = state in listOf(
|
||||
CALL_CONNECTED,
|
||||
CALL_OUTGOING,
|
||||
CALL_INCOMING
|
||||
) || (state == CALL_PRE_INIT && wantsToAnswer)
|
||||
remoteLoadingView.isVisible =
|
||||
state !in listOf(CALL_CONNECTED, CALL_RINGING, CALL_PRE_INIT) || wantsToAnswer
|
||||
incomingControlGroup.isVisible =
|
||||
state in listOf(CALL_RINGING, CALL_PRE_INIT) && !wantsToAnswer
|
||||
}
|
||||
} else {
|
||||
controlGroup.isVisible = state in listOf(CALL_CONNECTED, CALL_OUTGOING, CALL_INCOMING) || (state == CALL_PRE_INIT && wantsToAnswer)
|
||||
remote_loading_view.isVisible = state !in listOf(CALL_CONNECTED, CALL_RINGING, CALL_PRE_INIT) || wantsToAnswer
|
||||
incomingControlGroup.isVisible = state in listOf(CALL_RINGING, CALL_PRE_INIT) && !wantsToAnswer
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,7 +203,7 @@ class WebRtcCallActivity: PassphraseRequiredActionBarActivity() {
|
|||
viewModel.audioDeviceState.collect { state ->
|
||||
val speakerEnabled = state.selectedDevice == SPEAKER_PHONE
|
||||
// change drawable background to enabled or not
|
||||
speakerPhoneButton.isSelected = speakerEnabled
|
||||
binding.speakerPhoneButton.isSelected = speakerEnabled
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,20 +234,37 @@ class WebRtcCallActivity: PassphraseRequiredActionBarActivity() {
|
|||
supportActionBar?.title = displayName
|
||||
val signalProfilePicture = latestRecipient.recipient.contactPhoto
|
||||
val avatar = (signalProfilePicture as? ProfileContactPhoto)?.avatarObject
|
||||
val sizeInPX = resources.getDimensionPixelSize(R.dimen.extra_large_profile_picture_size)
|
||||
val sizeInPX =
|
||||
resources.getDimensionPixelSize(R.dimen.extra_large_profile_picture_size)
|
||||
if (signalProfilePicture != null && avatar != "0" && avatar != "") {
|
||||
glide.clear(remote_recipient)
|
||||
glide.load(signalProfilePicture).diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
|
||||
.circleCrop()
|
||||
.error(AvatarPlaceholderGenerator.generate(this@WebRtcCallActivity, sizeInPX, publicKey, displayName))
|
||||
.into(remote_recipient)
|
||||
glide.clear(binding.remoteRecipient)
|
||||
glide.load(signalProfilePicture)
|
||||
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
|
||||
.circleCrop()
|
||||
.error(
|
||||
AvatarPlaceholderGenerator.generate(
|
||||
this@WebRtcCallActivity,
|
||||
sizeInPX,
|
||||
publicKey,
|
||||
displayName
|
||||
)
|
||||
)
|
||||
.into(binding.remoteRecipient)
|
||||
} else {
|
||||
glide.clear(remote_recipient)
|
||||
glide.load(AvatarPlaceholderGenerator.generate(this@WebRtcCallActivity, sizeInPX, publicKey, displayName))
|
||||
.diskCacheStrategy(DiskCacheStrategy.ALL).circleCrop().into(remote_recipient)
|
||||
glide.clear(binding.remoteRecipient)
|
||||
glide.load(
|
||||
AvatarPlaceholderGenerator.generate(
|
||||
this@WebRtcCallActivity,
|
||||
sizeInPX,
|
||||
publicKey,
|
||||
displayName
|
||||
)
|
||||
)
|
||||
.diskCacheStrategy(DiskCacheStrategy.ALL).circleCrop()
|
||||
.into(binding.remoteRecipient)
|
||||
}
|
||||
} else {
|
||||
glide.clear(remote_recipient)
|
||||
glide.clear(binding.remoteRecipient)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -244,10 +273,13 @@ class WebRtcCallActivity: PassphraseRequiredActionBarActivity() {
|
|||
while (isActive) {
|
||||
val startTime = viewModel.callStartTime
|
||||
if (startTime == -1L) {
|
||||
callTime.isVisible = false
|
||||
binding.callTime.isVisible = false
|
||||
} else {
|
||||
callTime.isVisible = true
|
||||
callTime.text = DurationFormatUtils.formatDuration(System.currentTimeMillis() - startTime, CALL_DURATION_FORMAT)
|
||||
binding.callTime.isVisible = true
|
||||
binding.callTime.text = DurationFormatUtils.formatDuration(
|
||||
System.currentTimeMillis() - startTime,
|
||||
CALL_DURATION_FORMAT
|
||||
)
|
||||
}
|
||||
|
||||
delay(1_000)
|
||||
|
@ -257,48 +289,49 @@ class WebRtcCallActivity: PassphraseRequiredActionBarActivity() {
|
|||
launch {
|
||||
viewModel.localAudioEnabledState.collect { isEnabled ->
|
||||
// change drawable background to enabled or not
|
||||
microphoneButton.isSelected = !isEnabled
|
||||
binding.microphoneButton.isSelected = !isEnabled
|
||||
}
|
||||
}
|
||||
|
||||
launch {
|
||||
viewModel.localVideoEnabledState.collect { isEnabled ->
|
||||
local_renderer.removeAllViews()
|
||||
binding.localRenderer.removeAllViews()
|
||||
if (isEnabled) {
|
||||
viewModel.localRenderer?.let { surfaceView ->
|
||||
surfaceView.setZOrderOnTop(true)
|
||||
local_renderer.addView(surfaceView)
|
||||
binding.localRenderer.addView(surfaceView)
|
||||
}
|
||||
}
|
||||
local_renderer.isVisible = isEnabled
|
||||
enableCameraButton.isSelected = isEnabled
|
||||
binding.localRenderer.isVisible = isEnabled
|
||||
binding.enableCameraButton.isSelected = isEnabled
|
||||
}
|
||||
}
|
||||
|
||||
launch {
|
||||
viewModel.remoteVideoEnabledState.collect { isEnabled ->
|
||||
remote_renderer.removeAllViews()
|
||||
binding.remoteRenderer.removeAllViews()
|
||||
if (isEnabled) {
|
||||
viewModel.remoteRenderer?.let { surfaceView ->
|
||||
remote_renderer.addView(surfaceView)
|
||||
binding.remoteRenderer.addView(surfaceView)
|
||||
}
|
||||
}
|
||||
remote_renderer.isVisible = isEnabled
|
||||
remote_recipient.isVisible = !isEnabled
|
||||
binding.remoteRenderer.isVisible = isEnabled
|
||||
binding.remoteRecipient.isVisible = !isEnabled
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getUserDisplayName(publicKey: String): String {
|
||||
val contact = DatabaseComponent.get(this).sessionContactDatabase().getContactWithSessionID(publicKey)
|
||||
val contact =
|
||||
DatabaseComponent.get(this).sessionContactDatabase().getContactWithSessionID(publicKey)
|
||||
return contact?.displayName(Contact.ContactContext.REGULAR) ?: publicKey
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
uiJob?.cancel()
|
||||
remote_renderer.removeAllViews()
|
||||
local_renderer.removeAllViews()
|
||||
binding.remoteRenderer.removeAllViews()
|
||||
binding.localRenderer.removeAllViews()
|
||||
}
|
||||
}
|
|
@ -137,7 +137,6 @@ import java.util.concurrent.atomic.AtomicLong
|
|||
import java.util.concurrent.atomic.AtomicReference
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.math.sqrt
|
||||
|
@ -168,7 +167,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||
|
||||
private val screenWidth = Resources.getSystem().displayMetrics.widthPixels
|
||||
private val linkPreviewViewModel: LinkPreviewViewModel by lazy {
|
||||
ViewModelProvider(this, LinkPreviewViewModel.Factory(LinkPreviewRepository(this)))
|
||||
ViewModelProvider(this, LinkPreviewViewModel.Factory(LinkPreviewRepository()))
|
||||
.get(LinkPreviewViewModel::class.java)
|
||||
}
|
||||
private val viewModel: ConversationViewModel by viewModels {
|
||||
|
@ -542,7 +541,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
|
||||
ConversationMenuHelper.onPrepareOptionsMenu(menu, menuInflater, viewModel.recipient, viewModel.threadId, this) { onOptionsItemSelected(it) }
|
||||
ConversationMenuHelper.onPrepareOptionsMenu(menu, menuInflater, viewModel.recipient, viewModel.threadId, textSecurePreferences.isCallNotificationsEnabled(), this) { onOptionsItemSelected(it) }
|
||||
super.onPrepareOptionsMenu(menu)
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ import java.io.IOException
|
|||
|
||||
object ConversationMenuHelper {
|
||||
|
||||
fun onPrepareOptionsMenu(menu: Menu, inflater: MenuInflater, thread: Recipient, threadId: Long, context: Context, onOptionsItemSelected: (MenuItem) -> Unit) {
|
||||
fun onPrepareOptionsMenu(menu: Menu, inflater: MenuInflater, thread: Recipient, threadId: Long, isCallsEnabled: Boolean, context: Context, onOptionsItemSelected: (MenuItem) -> Unit) {
|
||||
// Prepare
|
||||
menu.clear()
|
||||
val isOpenGroup = thread.isOpenGroupRecipient
|
||||
|
@ -102,7 +102,7 @@ object ConversationMenuHelper {
|
|||
inflater.inflate(R.menu.menu_conversation_notification_settings, menu)
|
||||
}
|
||||
|
||||
if (!thread.isGroupRecipient && TextSecurePreferences.isCallNotificationsEnabled(context)) {
|
||||
if (!thread.isGroupRecipient && isCallsEnabled) {
|
||||
inflater.inflate(R.menu.menu_conversation_call, menu)
|
||||
}
|
||||
|
||||
|
|
|
@ -12,14 +12,11 @@ import android.widget.Toast
|
|||
import androidx.activity.viewModels
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.loader.app.LoaderManager
|
||||
import androidx.loader.content.Loader
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.collect
|
||||
|
@ -34,9 +31,6 @@ import org.greenrobot.eventbus.Subscribe
|
|||
import org.greenrobot.eventbus.ThreadMode
|
||||
import org.session.libsession.messaging.jobs.JobQueue
|
||||
import org.session.libsession.messaging.sending_receiving.MessageSender
|
||||
import org.session.libsession.messaging.utilities.WebRtcUtils
|
||||
import org.session.libsession.utilities.Util
|
||||
import org.session.libsignal.protos.SignalServiceProtos
|
||||
import org.session.libsession.utilities.Address
|
||||
import org.session.libsession.utilities.GroupUtil
|
||||
import org.session.libsession.utilities.ProfilePictureModifiedEvent
|
||||
|
@ -48,7 +42,6 @@ import org.session.libsignal.utilities.toHexString
|
|||
import org.thoughtcrime.securesms.ApplicationContext
|
||||
import org.thoughtcrime.securesms.MuteDialog
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
||||
import org.thoughtcrime.securesms.calls.WebRtcCallActivity
|
||||
import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2
|
||||
import org.thoughtcrime.securesms.conversation.v2.utilities.NotificationUtils
|
||||
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
||||
|
@ -76,7 +69,6 @@ import org.thoughtcrime.securesms.util.UiModeUtilities
|
|||
import org.thoughtcrime.securesms.util.disableClipping
|
||||
import org.thoughtcrime.securesms.util.push
|
||||
import org.thoughtcrime.securesms.util.show
|
||||
import org.thoughtcrime.securesms.webrtc.CallBottomSheet
|
||||
|
||||
import java.io.IOException
|
||||
import javax.inject.Inject
|
||||
|
|
|
@ -21,6 +21,9 @@ import org.thoughtcrime.securesms.service.KeyCachingService;
|
|||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import mobi.upod.timedurationpicker.TimeDurationPickerDialog;
|
||||
import network.loki.messenger.R;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package org.thoughtcrime.securesms.webrtc
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import org.thoughtcrime.securesms.webrtc.audio.OutgoingRinger
|
||||
import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager
|
||||
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
package org.thoughtcrime.securesms.webrtc
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.os.bundleOf
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import kotlinx.android.synthetic.main.fragment_call_bottom_sheet.*
|
||||
import kotlinx.android.synthetic.main.fragment_user_details_bottom_sheet.nameTextView
|
||||
import kotlinx.android.synthetic.main.fragment_user_details_bottom_sheet.profilePictureView
|
||||
import network.loki.messenger.R
|
||||
import org.session.libsession.messaging.messages.control.CallMessage
|
||||
import org.session.libsession.messaging.sending_receiving.MessageSender
|
||||
import org.session.libsession.utilities.Address
|
||||
import org.session.libsession.utilities.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.calls.WebRtcCallActivity
|
||||
import org.thoughtcrime.securesms.mms.GlideApp
|
||||
import java.util.*
|
||||
|
||||
class CallBottomSheet: BottomSheetDialogFragment() {
|
||||
|
||||
companion object {
|
||||
const val ARGUMENT_ADDRESS = "CallBottomSheet_ADDRESS"
|
||||
const val ARGUMENT_SDP = "CallBottomSheet_SDP"
|
||||
const val ARGUMENT_TYPE = "CallBottomSheet_TYPE"
|
||||
const val ARGUMENT_CALL_ID = "CallBottomSheet_CALL_ID"
|
||||
}
|
||||
|
||||
private lateinit var address: Address
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
return inflater.inflate(R.layout.fragment_call_bottom_sheet, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
address = arguments?.getParcelable(ARGUMENT_ADDRESS) ?: return dismiss()
|
||||
val sdp = arguments?.getStringArray(ARGUMENT_SDP) ?: return dismiss()
|
||||
val callId = arguments?.getString(ARGUMENT_CALL_ID) ?: return dismiss()
|
||||
val callUUID = UUID.fromString(callId)
|
||||
val recipient = Recipient.from(requireContext(), address, false)
|
||||
profilePictureView.publicKey = address.serialize()
|
||||
profilePictureView.glide = GlideApp.with(this)
|
||||
profilePictureView.isLarge = true
|
||||
profilePictureView.update(recipient, -1)
|
||||
|
||||
nameTextView.text = recipient.name ?: address.serialize()
|
||||
|
||||
acceptButton.setOnClickListener {
|
||||
// val intent = Intent(requireContext(), WebRtcCallActivity::class.java)
|
||||
// val bundle = bundleOf(
|
||||
// WebRtcCallActivity.EXTRA_ADDRESS to address,
|
||||
// WebRtcCallActivity.EXTRA_CALL_ID to callId
|
||||
// )
|
||||
// intent.action = WebRtcCallActivity.ACTION_ANSWER
|
||||
// bundle.putStringArray(WebRtcCallActivity.EXTRA_SDP, sdp)
|
||||
//
|
||||
// intent.putExtras(bundle)
|
||||
// startActivity(intent)
|
||||
// dismiss()
|
||||
}
|
||||
|
||||
declineButton.setOnClickListener {
|
||||
MessageSender.sendNonDurably(CallMessage.endCall(callUUID), address)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -21,7 +21,7 @@ import org.thoughtcrime.securesms.util.CallNotificationBuilder
|
|||
import org.webrtc.IceCandidate
|
||||
|
||||
|
||||
class CallMessageProcessor(private val context: Context, lifecycle: Lifecycle, private val storage: StorageProtocol) {
|
||||
class CallMessageProcessor(private val context: Context, private val textSecurePreferences: TextSecurePreferences, lifecycle: Lifecycle, private val storage: StorageProtocol) {
|
||||
|
||||
init {
|
||||
lifecycle.coroutineScope.launch(IO) {
|
||||
|
@ -31,11 +31,11 @@ class CallMessageProcessor(private val context: Context, lifecycle: Lifecycle, p
|
|||
val sender = nextMessage.sender ?: continue
|
||||
if (!storage.conversationHasOutgoing(sender) && storage.getUserPublicKey() != sender) continue
|
||||
|
||||
if (!TextSecurePreferences.isCallNotificationsEnabled(context)) {
|
||||
if (!textSecurePreferences.isCallNotificationsEnabled()) {
|
||||
Log.d("Loki","Dropping call message if call notifications disabled")
|
||||
if (nextMessage.type != PRE_OFFER) continue
|
||||
val sentTimestamp = nextMessage.sentTimestamp ?: continue
|
||||
if (TextSecurePreferences.setShownCallNotification(context)) {
|
||||
if (textSecurePreferences.setShownCallNotification()) {
|
||||
// first time call notification encountered
|
||||
val notification = CallNotificationBuilder.getFirstCallNotification(context)
|
||||
context.getSystemService(NotificationManager::class.java).notify(CallNotificationBuilder.WEBRTC_NOTIFICATION, notification)
|
||||
|
|
|
@ -60,7 +60,7 @@ private fun MessageReceiver.handleReadReceipt(message: ReadReceipt) {
|
|||
|
||||
private fun MessageReceiver.handleCallMessage(message: CallMessage) {
|
||||
// TODO: refactor this out to persistence, just to help debug the flow and send/receive in synchronous testing
|
||||
WebRtcUtils.SIGNAL_QUEUE.offer(message)
|
||||
WebRtcUtils.SIGNAL_QUEUE.trySend(message)
|
||||
}
|
||||
|
||||
private fun MessageReceiver.handleTypingIndicator(message: TypingIndicator) {
|
||||
|
|
|
@ -12,6 +12,9 @@ import kotlinx.coroutines.channels.BufferOverflow
|
|||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.asSharedFlow
|
||||
import org.session.libsession.R
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.CALL_NOTIFICATIONS_ENABLED
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.SHOWN_CALL_NOTIFICATION
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.SHOWN_CALL_WARNING
|
||||
import org.session.libsignal.utilities.Log
|
||||
import java.io.IOException
|
||||
import java.util.Arrays
|
||||
|
@ -151,6 +154,9 @@ interface TextSecurePreferences {
|
|||
fun setLastOpenDate()
|
||||
fun hasSeenLinkPreviewSuggestionDialog(): Boolean
|
||||
fun setHasSeenLinkPreviewSuggestionDialog()
|
||||
fun setShownCallWarning(): Boolean
|
||||
fun setShownCallNotification(): Boolean
|
||||
fun isCallNotificationsEnabled(): Boolean
|
||||
fun clearAll()
|
||||
|
||||
companion object {
|
||||
|
@ -228,8 +234,8 @@ interface TextSecurePreferences {
|
|||
const val LAST_PROFILE_UPDATE_TIME = "pref_last_profile_update_time"
|
||||
const val LAST_OPEN_DATE = "pref_last_open_date"
|
||||
const val CALL_NOTIFICATIONS_ENABLED = "pref_call_notifications_enabled"
|
||||
private const val SHOWN_CALL_WARNING = "pref_shown_call_warning" // call warning is user-facing warning of enabling calls
|
||||
private const val SHOWN_CALL_NOTIFICATION = "pref_shown_call_notification" // call notification is a promp to check privacy settings
|
||||
const val SHOWN_CALL_WARNING = "pref_shown_call_warning" // call warning is user-facing warning of enabling calls
|
||||
const val SHOWN_CALL_NOTIFICATION = "pref_shown_call_notification" // call notification is a promp to check privacy settings
|
||||
|
||||
@JvmStatic
|
||||
fun getLastConfigurationSyncTime(context: Context): Long {
|
||||
|
@ -873,6 +879,17 @@ interface TextSecurePreferences {
|
|||
setBooleanPreference(context, "has_seen_link_preview_suggestion_dialog", true)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun setShownCallWarning(context: Context): Boolean {
|
||||
val previousValue = getBooleanPreference(context, SHOWN_CALL_WARNING, false)
|
||||
if (previousValue) {
|
||||
return false
|
||||
}
|
||||
val setValue = true
|
||||
setBooleanPreference(context, SHOWN_CALL_WARNING, setValue)
|
||||
return previousValue != setValue
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun clearAll(context: Context) {
|
||||
getDefaultSharedPreferences(context).edit().clear().commit()
|
||||
|
@ -1429,21 +1446,15 @@ class AppTextSecurePreferences @Inject constructor(
|
|||
setBooleanPreference("has_seen_link_preview_suggestion_dialog", true)
|
||||
}
|
||||
|
||||
override fun clearAll() {
|
||||
getDefaultSharedPreferences(context).edit().clear().commit()
|
||||
override fun isCallNotificationsEnabled(): Boolean {
|
||||
return getBooleanPreference(CALL_NOTIFICATIONS_ENABLED, false)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun isCallNotificationsEnabled(context: Context): Boolean {
|
||||
return getBooleanPreference(context, CALL_NOTIFICATIONS_ENABLED, false)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun setShownCallNotification(context: Context): Boolean {
|
||||
val previousValue = getBooleanPreference(context, SHOWN_CALL_NOTIFICATION, false)
|
||||
override fun setShownCallNotification(): Boolean {
|
||||
val previousValue = getBooleanPreference(SHOWN_CALL_NOTIFICATION, false)
|
||||
if (previousValue) return false
|
||||
val setValue = true
|
||||
setBooleanPreference(context, SHOWN_CALL_NOTIFICATION, setValue)
|
||||
setBooleanPreference(SHOWN_CALL_NOTIFICATION, setValue)
|
||||
return previousValue != setValue
|
||||
}
|
||||
|
||||
|
@ -1452,15 +1463,18 @@ class AppTextSecurePreferences @Inject constructor(
|
|||
* Set the SHOWN_CALL_WARNING preference to `true`
|
||||
* Return `true` if the value did update (it was previously unset)
|
||||
*/
|
||||
@JvmStatic
|
||||
fun setShownCallWarning(context: Context) : Boolean {
|
||||
val previousValue = getBooleanPreference(context, SHOWN_CALL_WARNING, false)
|
||||
override fun setShownCallWarning() : Boolean {
|
||||
val previousValue = getBooleanPreference(SHOWN_CALL_WARNING, false)
|
||||
if (previousValue) {
|
||||
return false
|
||||
}
|
||||
val setValue = true
|
||||
setBooleanPreference(context, SHOWN_CALL_WARNING, setValue)
|
||||
setBooleanPreference(SHOWN_CALL_WARNING, setValue)
|
||||
return previousValue != setValue
|
||||
}
|
||||
|
||||
override fun clearAll() {
|
||||
getDefaultSharedPreferences(context).edit().clear().commit()
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue