Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add VoIP bug report type #1010

Merged
merged 4 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/1010.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add VoIP bug report button
3 changes: 2 additions & 1 deletion library/ui-strings/src/main/res/values-fr/strings_tchap.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
<string name="tchap_room_settings_room_access_restricted">Les externes ne sont pas autorisés à rejoindre ce salon</string>
<string name="tchap_room_settings_room_access_unrestricted">Les externes sont autorisés à rejoindre ce salon</string>
<string name="tchap_room_settings_allow_external_users_to_join">Autoriser l’accès aux externes à ce salon</string>
<string name="tchap_room_settings_allow_external_users_to_join_prompt_msg"><b>Cette action est irréversible.</b>\nVoulez-vous vraiment autoriser les externes à rejoindre ce salon ?</string>
<string name="tchap_room_settings_allow_external_users_to_join_prompt_msg"><b>Cette action est irréversible.</b>\nVoulez-vous vraiment autoriser les externes à rejoindre ce salon ?</string>
<string name="tchap_room_settings_room_access_by_link_title">Accès par lien</string>
<string name="tchap_room_settings_room_access_by_link_disabled">Ce salon n’est pas accessible par lien</string>
<string name="tchap_room_settings_room_access_by_link_enabled">Ce salon est accessible par lien</string>
Expand Down Expand Up @@ -100,6 +100,7 @@

<!-- Call -->
<string name="tchap_call_not_supported">${app_name} ne supporte pas les appels</string>
<string name="tchap_call_tile_reported">Signaler un problème</string>

<!-- Home drawer -->
<string name="tchap_invite_to">Inviter à rejoindre ${app_name}</string>
Expand Down
1 change: 1 addition & 0 deletions library/ui-strings/src/main/res/values/strings_tchap.xml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@

<!-- Call -->
<string name="tchap_call_not_supported">${app_name} does not support calls</string>
<string name="tchap_call_tile_reported">Report an issue</string>

<!-- Home drawer -->
<string name="tchap_invite_to">Invite to join ${app_name}</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -97,7 +98,15 @@ abstract class CallTileTimelineItem : AbsBaseMessageItem<CallTileTimelineItem.Ho
}

private fun renderEndedStatus(holder: Holder) {
holder.acceptRejectViewGroup.isVisible = false
// Tchap: Add button to report issues about voip
holder.acceptRejectViewGroup.isVisible = true
holder.rejectView.isVisible = false
holder.acceptView.setText(R.string.tchap_call_tile_reported)
holder.acceptView.clearDrawables()
holder.acceptView.onClick {
val callbackAction = RoomDetailAction.SendCallFeedback
attributes.callback?.onTimelineItemAction(callbackAction)
}
when (attributes.callKind) {
CallKind.VIDEO -> {
val endCallStatus = holder.resources.getString(R.string.call_tile_video_call_has_ended, attributes.formattedDuration)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -545,6 +559,36 @@ class BugReporter @Inject constructor(
}
)
}

// Tchap: add connection type in VoIP report
private fun getConnectionType(): String {
val connectivityManager = context.getSystemService<ConnectivityManager>()!!
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
// ==============================================================================================================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ enum class ReportType {
THREADS_BETA_FEEDBACK,
AUTO_UISI,
AUTO_UISI_SENDER,
VOIP,
}
Loading