From 53127b69de86ba4ac92aa4537b4edc3cf71aa63e Mon Sep 17 00:00:00 2001 From: jubb Date: Tue, 8 Feb 2022 12:04:55 +1100 Subject: [PATCH] refactor: compile errors and refactoring to view binding --- app/build.gradle | 3 +- .../securesms/ApplicationContext.java | 3 +- .../securesms/calls/WebRtcCallActivity.kt | 169 +++++++++++------- .../conversation/v2/ConversationActivityV2.kt | 5 +- .../v2/menus/ConversationMenuHelper.kt | 4 +- .../securesms/home/HomeActivity.kt | 8 - .../AppProtectionPreferenceFragment.java | 3 + .../securesms/webrtc/AudioManagerCommand.kt | 2 +- .../securesms/webrtc/CallBottomSheet.kt | 76 -------- .../securesms/webrtc/CallMessageProcessor.kt | 6 +- .../ReceivedMessageHandler.kt | 2 +- .../utilities/TextSecurePreferences.kt | 48 +++-- 12 files changed, 148 insertions(+), 181 deletions(-) delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/webrtc/CallBottomSheet.kt diff --git a/app/build.gradle b/app/build.gradle index b5d1ff6ee..009221e7c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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 diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index 5a2a6a146..6dd1cc936 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -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(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/WebRtcCallActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/WebRtcCallActivity.kt index 3e6ccc28b..a8a741e27 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/WebRtcCallActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/WebRtcCallActivity.kt @@ -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() 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() } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index fc181d79c..8fd780faa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -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 } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt index 740cb648a..dce7e9c3b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt @@ -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) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt index a9860a284..caf2dffb6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt @@ -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 diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java b/app/src/main/java/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java index 14113975c..d310398a0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java @@ -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; diff --git a/app/src/main/java/org/thoughtcrime/securesms/webrtc/AudioManagerCommand.kt b/app/src/main/java/org/thoughtcrime/securesms/webrtc/AudioManagerCommand.kt index a035d0440..c6dd6525e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/webrtc/AudioManagerCommand.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/webrtc/AudioManagerCommand.kt @@ -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 diff --git a/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallBottomSheet.kt b/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallBottomSheet.kt deleted file mode 100644 index f167c5ff5..000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallBottomSheet.kt +++ /dev/null @@ -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() - } - - } -} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallMessageProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallMessageProcessor.kt index 5e06c3bee..5a72f9a99 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallMessageProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallMessageProcessor.kt @@ -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) diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt index 79d89f0aa..28b1fed9f 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt @@ -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) { diff --git a/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt b/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt index 2b46af874..80ccf9d85 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt +++ b/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt @@ -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() + } + } \ No newline at end of file