From 0203662817da0d9fc35cefc3e374e45b6d1257a9 Mon Sep 17 00:00:00 2001 From: yostyle Date: Tue, 6 Feb 2024 00:31:22 +0100 Subject: [PATCH 1/4] Add VoIP bug report type --- .../src/main/res/values-fr/strings_tchap.xml | 3 +- .../src/main/res/values/strings_tchap.xml | 1 + .../home/room/detail/RoomDetailAction.kt | 1 + .../home/room/detail/RoomDetailViewEvents.kt | 1 + .../home/room/detail/TimelineFragment.kt | 4 ++ .../home/room/detail/TimelineViewModel.kt | 5 ++ .../timeline/item/CallTileTimelineItem.kt | 11 ++++- .../app/features/rageshake/BugReporter.kt | 46 ++++++++++++++++++- .../app/features/rageshake/ReportType.kt | 1 + 9 files changed, 70 insertions(+), 3 deletions(-) diff --git a/library/ui-strings/src/main/res/values-fr/strings_tchap.xml b/library/ui-strings/src/main/res/values-fr/strings_tchap.xml index 786923fc98..6feed18800 100644 --- a/library/ui-strings/src/main/res/values-fr/strings_tchap.xml +++ b/library/ui-strings/src/main/res/values-fr/strings_tchap.xml @@ -57,7 +57,7 @@ Les externes ne sont pas autorisés à rejoindre ce salon Les externes sont autorisés à rejoindre ce salon Autoriser l’accès aux externes à ce salon - Cette action est irréversible.\nVoulez-vous vraiment autoriser les externes à rejoindre ce salon ? + Cette action est irréversible.\nVoulez-vous vraiment autoriser les externes à rejoindre ce salon ? Accès par lien Ce salon n’est pas accessible par lien Ce salon est accessible par lien @@ -100,6 +100,7 @@ ${app_name} ne supporte pas les appels + Rapporter un problème ? Inviter à rejoindre ${app_name} diff --git a/library/ui-strings/src/main/res/values/strings_tchap.xml b/library/ui-strings/src/main/res/values/strings_tchap.xml index 7e687b0c4d..5738339a48 100644 --- a/library/ui-strings/src/main/res/values/strings_tchap.xml +++ b/library/ui-strings/src/main/res/values/strings_tchap.xml @@ -100,6 +100,7 @@ ${app_name} does not support calls + Report an issue? Invite to join ${app_name} diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt index 478ed4a58d..c1e64f5f01 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt @@ -71,6 +71,7 @@ sealed class RoomDetailAction : VectorViewModelAction { data class StartCall(val isVideo: Boolean) : RoomDetailAction() data class AcceptCall(val callId: String) : RoomDetailAction() object EndCall : RoomDetailAction() + object SendCallFeedback : RoomDetailAction() data class AcceptVerificationRequest(val transactionId: String, val otherUserId: String) : RoomDetailAction() data class DeclineVerificationRequest(val transactionId: String, val otherUserId: String) : RoomDetailAction() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt index 1183951b45..0799c3657b 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt @@ -45,6 +45,7 @@ sealed class RoomDetailViewEvents : VectorViewEvents { data class JoinJitsiConference(val widget: Widget, val withVideo: Boolean) : RoomDetailViewEvents() object LeaveJitsiConference : RoomDetailViewEvents() + object SendCallFeedback : RoomDetailViewEvents() object OpenInvitePeople : RoomDetailViewEvents() object OpenSetRoomAvatarDialog : RoomDetailViewEvents() object OpenRoomSettings : RoomDetailViewEvents() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index 708a2930f7..d284e9d054 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -174,6 +174,8 @@ import im.vector.app.features.permalink.NavigationInterceptor import im.vector.app.features.permalink.PermalinkFactory import im.vector.app.features.permalink.PermalinkHandler import im.vector.app.features.poll.PollMode +import im.vector.app.features.rageshake.BugReporter +import im.vector.app.features.rageshake.ReportType import im.vector.app.features.reactions.EmojiReactionPickerActivity import im.vector.app.features.roomprofile.RoomProfileActivity import im.vector.app.features.session.coroutineScope @@ -230,6 +232,7 @@ class TimelineFragment : CurrentCallsView.Callback, VectorMenuProvider { + @Inject lateinit var bugReporter: BugReporter @Inject lateinit var session: Session @Inject lateinit var avatarRenderer: AvatarRenderer @Inject lateinit var timelineEventController: TimelineEventController @@ -380,6 +383,7 @@ class TimelineFragment : timelineViewModel.observeViewEvents { when (it) { + is RoomDetailViewEvents.SendCallFeedback -> bugReporter.openBugReportScreen(requireActivity(), ReportType.VOIP) is RoomDetailViewEvents.Failure -> displayErrorMessage(it) is RoomDetailViewEvents.OnNewTimelineEvents -> scrollOnNewMessageCallback.addNewTimelineEventIds(it.eventIds) is RoomDetailViewEvents.ActionSuccess -> displayRoomDetailActionSuccess(it) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt index 413c1ca502..3d1f9eb316 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt @@ -498,6 +498,7 @@ class TimelineViewModel @AssistedInject constructor( is RoomDetailAction.StartCall -> handleStartCall(action) is RoomDetailAction.AcceptCall -> handleAcceptCall(action) is RoomDetailAction.EndCall -> handleEndCall() + is RoomDetailAction.SendCallFeedback -> handleSendCallFeedback() is RoomDetailAction.ManageIntegrations -> handleManageIntegrations() is RoomDetailAction.AddJitsiWidget -> handleAddJitsiConference(action) is RoomDetailAction.UpdateJoinJitsiCallStatus -> handleJitsiCallJoinStatus(action) @@ -628,6 +629,10 @@ class TimelineViewModel @AssistedInject constructor( callManager.endCallForRoom(initialState.roomId) } + private fun handleSendCallFeedback() { + _viewEvents.post(RoomDetailViewEvents.SendCallFeedback) + } + private fun handleSelectStickerAttachment() { viewModelScope.launch { val viewEvent = stickerPickerActionHandler.handle() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/CallTileTimelineItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/CallTileTimelineItem.kt index 7d846a78aa..dfde57c835 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/CallTileTimelineItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/CallTileTimelineItem.kt @@ -31,6 +31,7 @@ import com.airbnb.epoxy.EpoxyModelClass import im.vector.app.R import im.vector.app.core.epoxy.ClickListener import im.vector.app.core.epoxy.onClick +import im.vector.app.core.extensions.clearDrawables import im.vector.app.core.extensions.setLeftDrawable import im.vector.app.core.extensions.setTextOrHide import im.vector.app.features.displayname.getBestName @@ -97,7 +98,15 @@ abstract class CallTileTimelineItem : AbsBaseMessageItem { val endCallStatus = holder.resources.getString(R.string.call_tile_video_call_has_ended, attributes.formattedDuration) diff --git a/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt b/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt index f9a578acc4..3070b65525 100755 --- a/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt +++ b/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt @@ -17,11 +17,17 @@ package im.vector.app.features.rageshake import android.annotation.SuppressLint +import android.bluetooth.BluetoothAdapter +import android.bluetooth.BluetoothHeadset +import android.bluetooth.BluetoothManager import android.content.Context import android.graphics.Bitmap import android.graphics.Canvas +import android.net.ConnectivityManager +import android.net.NetworkCapabilities import android.os.Build import android.view.View +import androidx.core.content.getSystemService import androidx.fragment.app.DialogFragment import androidx.fragment.app.FragmentActivity import com.squareup.moshi.Types @@ -165,7 +171,7 @@ class BugReporter @Inject constructor( /** * Send a bug report. * - * @param reportType The report type (bug, suggestion, feedback) + * @param reportType The report type (bug, suggestion, feedback, voip) * @param withDevicesLogs true to include the device log * @param withCrashLogs true to include the crash logs * @param withKeyRequestHistory true to include the crash logs @@ -283,6 +289,7 @@ class BugReporter @Inject constructor( val text = when (reportType) { // Tchap: Use BuildConfig.FLAVOR_target instead of Element ReportType.BUG_REPORT -> "[${BuildConfig.FLAVOR_target}] $bugDescription" + ReportType.VOIP -> "[${BuildConfig.FLAVOR_target}] [voip-feedback] $bugDescription" // Tchap: add VoIP report type ReportType.SUGGESTION -> "[${BuildConfig.FLAVOR_target}] [Suggestion] $bugDescription" ReportType.SPACE_BETA_FEEDBACK -> "[${BuildConfig.FLAVOR_target}] [spaces-feedback] $bugDescription" ReportType.THREADS_BETA_FEEDBACK -> "[${BuildConfig.FLAVOR_target}] [threads-feedback] $bugDescription" @@ -370,6 +377,13 @@ class BugReporter @Inject constructor( ReportType.BUG_REPORT -> { /* nop */ } + // Tchap: add VoIP report type + ReportType.VOIP -> { + builder.addFormDataPart("label", "voip-feedback") + builder.addFormDataPart("context", "voip") + builder.addFormDataPart("connection", getConnectionType()) + if (isBluetoothHeadsetConnected()) builder.addFormDataPart("audio_input", "headset_bluetooth") + } ReportType.SUGGESTION -> builder.addFormDataPart("label", "[Suggestion]") ReportType.SPACE_BETA_FEEDBACK -> builder.addFormDataPart("label", "spaces-feedback") ReportType.THREADS_BETA_FEEDBACK -> builder.addFormDataPart("label", "threads-feedback") @@ -545,6 +559,36 @@ class BugReporter @Inject constructor( } ) } + + // Tchap: add connection type in VoIP report + private fun getConnectionType():String { + val connectivityManager = context.getSystemService()!! + return if (sdkIntProvider.isAtLeast(Build.VERSION_CODES.M)) { + val networkCapabilities = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork) + when { + networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_VPN) == true -> "vpn" + networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) == true -> "wifi" + networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == true -> "mobile" + else -> "unknown" + } + } else { + @Suppress("DEPRECATION") + when (connectivityManager.activeNetworkInfo?.type) { + ConnectivityManager.TYPE_VPN -> "vpn" + ConnectivityManager.TYPE_WIFI -> "wifi" + ConnectivityManager.TYPE_MOBILE -> "mobile" + else -> "unknown" + } + } + } + + // Tchap: check if a headset is connected + private fun isBluetoothHeadsetConnected(): Boolean { + val bm: BluetoothManager? = context.getSystemService() + return bm?.adapter?.let { + it.isEnabled && it.getProfileConnectionState(BluetoothHeadset.HEADSET) == BluetoothAdapter.STATE_CONNECTED + } ?: false + } // ============================================================================================================== // crash report management // ============================================================================================================== diff --git a/vector/src/main/java/im/vector/app/features/rageshake/ReportType.kt b/vector/src/main/java/im/vector/app/features/rageshake/ReportType.kt index f75420ea55..226a48c353 100644 --- a/vector/src/main/java/im/vector/app/features/rageshake/ReportType.kt +++ b/vector/src/main/java/im/vector/app/features/rageshake/ReportType.kt @@ -23,4 +23,5 @@ enum class ReportType { THREADS_BETA_FEEDBACK, AUTO_UISI, AUTO_UISI_SENDER, + VOIP, } From 76c9744d4565cf359d0f0b1711896c7792251e73 Mon Sep 17 00:00:00 2001 From: yostyle Date: Tue, 6 Feb 2024 00:52:56 +0100 Subject: [PATCH 2/4] Add changelog --- changelog.d/1010.misc | 1 + .../main/java/im/vector/app/features/rageshake/BugReporter.kt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelog.d/1010.misc diff --git a/changelog.d/1010.misc b/changelog.d/1010.misc new file mode 100644 index 0000000000..3cb6c1fcfa --- /dev/null +++ b/changelog.d/1010.misc @@ -0,0 +1 @@ +Add VoIP bug report button \ No newline at end of file diff --git a/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt b/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt index 3070b65525..dcff5c6cd2 100755 --- a/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt +++ b/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt @@ -561,7 +561,7 @@ class BugReporter @Inject constructor( } // Tchap: add connection type in VoIP report - private fun getConnectionType():String { + private fun getConnectionType(): String { val connectivityManager = context.getSystemService()!! return if (sdkIntProvider.isAtLeast(Build.VERSION_CODES.M)) { val networkCapabilities = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork) From a81c1dea508baaa7e1809b5ef9c9768fe0569693 Mon Sep 17 00:00:00 2001 From: yostyle Date: Tue, 6 Feb 2024 09:45:44 +0100 Subject: [PATCH 3/4] Update strings --- library/ui-strings/src/main/res/values-fr/strings_tchap.xml | 2 +- library/ui-strings/src/main/res/values/strings_tchap.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/ui-strings/src/main/res/values-fr/strings_tchap.xml b/library/ui-strings/src/main/res/values-fr/strings_tchap.xml index 6feed18800..08d4bc0c15 100644 --- a/library/ui-strings/src/main/res/values-fr/strings_tchap.xml +++ b/library/ui-strings/src/main/res/values-fr/strings_tchap.xml @@ -100,7 +100,7 @@ ${app_name} ne supporte pas les appels - Rapporter un problème ? + Signaler un problème Inviter à rejoindre ${app_name} diff --git a/library/ui-strings/src/main/res/values/strings_tchap.xml b/library/ui-strings/src/main/res/values/strings_tchap.xml index 5738339a48..635dd9b4ef 100644 --- a/library/ui-strings/src/main/res/values/strings_tchap.xml +++ b/library/ui-strings/src/main/res/values/strings_tchap.xml @@ -100,7 +100,7 @@ ${app_name} does not support calls - Report an issue? + Report an issue Invite to join ${app_name} From b5309c12c086cb6bc720dd881700d5b80ee42097 Mon Sep 17 00:00:00 2001 From: yostyle Date: Wed, 7 Feb 2024 10:30:35 +0100 Subject: [PATCH 4/4] Audio input is mandatory --- .../main/java/im/vector/app/features/rageshake/BugReporter.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt b/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt index dcff5c6cd2..a4abfce415 100755 --- a/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt +++ b/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt @@ -382,7 +382,7 @@ class BugReporter @Inject constructor( builder.addFormDataPart("label", "voip-feedback") builder.addFormDataPart("context", "voip") builder.addFormDataPart("connection", getConnectionType()) - if (isBluetoothHeadsetConnected()) builder.addFormDataPart("audio_input", "headset_bluetooth") + builder.addFormDataPart("audio_input", getAudioInterface()) } ReportType.SUGGESTION -> builder.addFormDataPart("label", "[Suggestion]") ReportType.SPACE_BETA_FEEDBACK -> builder.addFormDataPart("label", "spaces-feedback") @@ -583,6 +583,8 @@ class BugReporter @Inject constructor( } // Tchap: check if a headset is connected + private fun getAudioInterface() = if (isBluetoothHeadsetConnected()) "headset_bluetooth" else "device" + private fun isBluetoothHeadsetConnected(): Boolean { val bm: BluetoothManager? = context.getSystemService() return bm?.adapter?.let {