mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-15 07:28:30 +00:00
Add the call quality diagnostics fragment.
This commit is contained in:
@@ -76,6 +76,12 @@ class CallQualityBottomSheetFragment : ComposeBottomSheetDialogFragment() {
|
||||
)
|
||||
}
|
||||
|
||||
override fun viewDiagnostics() {
|
||||
CallQualityDiagnosticsFragment.create(
|
||||
viewModel.getRequestSnapshot()
|
||||
).show(parentFragmentManager, null)
|
||||
}
|
||||
|
||||
override fun onUserSatisfiedWithCall(isUserSatisfiedWithCall: Boolean) {
|
||||
viewModel.setUserSatisfiedWithCall(isUserSatisfiedWithCall)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2026 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.calls.quality
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.core.os.bundleOf
|
||||
import org.signal.storageservice.protos.calls.quality.SubmitCallQualitySurveyRequest
|
||||
import org.thoughtcrime.securesms.compose.ComposeFullScreenDialogFragment
|
||||
|
||||
class CallQualityDiagnosticsFragment : ComposeFullScreenDialogFragment() {
|
||||
|
||||
companion object {
|
||||
private const val REQUEST_KEY = "CallQualityDiagnosticsRequestKey"
|
||||
|
||||
fun create(request: SubmitCallQualitySurveyRequest): CallQualityDiagnosticsFragment {
|
||||
return CallQualityDiagnosticsFragment().apply {
|
||||
arguments = bundleOf(REQUEST_KEY to request.encode())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val callQualitySurveyRequest: SubmitCallQualitySurveyRequest by lazy {
|
||||
val bytes = requireArguments().getByteArray(REQUEST_KEY)!!
|
||||
SubmitCallQualitySurveyRequest.ADAPTER.decode(bytes)
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun DialogContent() {
|
||||
CallQualityDiagnosticsScreen(
|
||||
callQualitySurveyRequest = callQualitySurveyRequest,
|
||||
onNavigationClick = { requireActivity().onBackPressedDispatcher.onBackPressed() }
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2026 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.calls.quality
|
||||
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.signal.core.ui.compose.Buttons
|
||||
import org.signal.core.ui.compose.DayNightPreviews
|
||||
import org.signal.core.ui.compose.Previews
|
||||
import org.signal.core.ui.compose.Scaffolds
|
||||
import org.signal.core.ui.compose.horizontalGutters
|
||||
import org.signal.storageservice.protos.calls.quality.SubmitCallQualitySurveyRequest
|
||||
import org.thoughtcrime.securesms.R
|
||||
|
||||
@Composable
|
||||
fun CallQualityDiagnosticsScreen(
|
||||
callQualitySurveyRequest: SubmitCallQualitySurveyRequest,
|
||||
onNavigationClick: () -> Unit = {}
|
||||
) {
|
||||
Scaffolds.Settings(
|
||||
title = stringResource(R.string.CallQualityDiagnosticsScreen__diagnostic_information),
|
||||
navigationIcon = ImageVector.vectorResource(R.drawable.symbol_arrow_start_24),
|
||||
navigationContentDescription = stringResource(R.string.CallQualityDiagnosticsScreen__close),
|
||||
onNavigationClick = onNavigationClick
|
||||
) {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier
|
||||
.padding(it)
|
||||
.fillMaxSize()
|
||||
.horizontalGutters()
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
Text(
|
||||
text = callQualitySurveyRequest.toString().substringAfter(SubmitCallQualitySurveyRequest::class.simpleName ?: "")
|
||||
)
|
||||
}
|
||||
|
||||
Buttons.LargeTonal(
|
||||
onClick = onNavigationClick,
|
||||
modifier = Modifier
|
||||
.padding(top = 10.dp, bottom = 24.dp)
|
||||
.widthIn(min = 256.dp)
|
||||
) {
|
||||
Text(text = stringResource(R.string.CallQualityDiagnosticsScreen__close))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DayNightPreviews
|
||||
@Composable
|
||||
private fun CallQualityDiagnosticsScreenPreview() {
|
||||
Previews.Preview {
|
||||
CallQualityDiagnosticsScreen(
|
||||
callQualitySurveyRequest = SubmitCallQualitySurveyRequest()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -58,6 +58,10 @@ class CallQualityScreenViewModel(
|
||||
return
|
||||
}
|
||||
|
||||
AppDependencies.jobManager.add(CallQualitySurveySubmissionJob(getRequestSnapshot(), state.value.isShareDebugLogSelected))
|
||||
}
|
||||
|
||||
fun getRequestSnapshot(): SubmitCallQualitySurveyRequest {
|
||||
val stateSnapshot = state.value
|
||||
val somethingElseDescription: String? = if (stateSnapshot.selectedQualityIssues.contains(CallQualityIssue.SOMETHING_ELSE)) {
|
||||
stateSnapshot.somethingElseDescription.takeIf { it.isNotEmpty() }
|
||||
@@ -65,12 +69,10 @@ class CallQualityScreenViewModel(
|
||||
null
|
||||
}
|
||||
|
||||
val requestToSubmitToJob = initialRequest.newBuilder()
|
||||
return initialRequest.newBuilder()
|
||||
.user_satisfied(stateSnapshot.isUserSatisfiedWithCall)
|
||||
.call_quality_issues(stateSnapshot.selectedQualityIssues.map { it.code })
|
||||
.additional_issues_description(somethingElseDescription)
|
||||
.build()
|
||||
|
||||
AppDependencies.jobManager.add(CallQualitySurveySubmissionJob(requestToSubmitToJob, stateSnapshot.isShareDebugLogSelected))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,6 +141,7 @@ fun CallQualitySheet(
|
||||
CallQualitySheetNavEntry.HelpUsImprove -> HelpUsImprove(
|
||||
isShareDebugLogSelected = state.isShareDebugLogSelected,
|
||||
onViewDebugLogClick = callback::viewDebugLog,
|
||||
onViewDiagnosticsClick = callback::viewDiagnostics,
|
||||
onCancelClick = callback::dismiss,
|
||||
onShareDebugLogChanged = callback::onShareDebugLogChanged,
|
||||
onSubmitClick = callback::submit
|
||||
@@ -431,6 +432,7 @@ private fun IssueChip(
|
||||
private fun HelpUsImprove(
|
||||
isShareDebugLogSelected: Boolean,
|
||||
onShareDebugLogChanged: (Boolean) -> Unit,
|
||||
onViewDiagnosticsClick: () -> Unit,
|
||||
onViewDebugLogClick: () -> Unit,
|
||||
onCancelClick: () -> Unit,
|
||||
onSubmitClick: () -> Unit
|
||||
@@ -443,12 +445,12 @@ private fun HelpUsImprove(
|
||||
|
||||
withLink(
|
||||
link = LinkAnnotation.Clickable(
|
||||
"view-your-debug-log",
|
||||
linkInteractionListener = { onViewDebugLogClick() },
|
||||
"view-diagnostics",
|
||||
linkInteractionListener = { onViewDiagnosticsClick() },
|
||||
styles = TextLinkStyles(style = SpanStyle(color = MaterialTheme.colorScheme.primary))
|
||||
)
|
||||
) {
|
||||
append(stringResource(R.string.CallQualitySheet__view_your_debug_log))
|
||||
append(stringResource(R.string.CallQualitySheet__diagnostic_information_about_your_call))
|
||||
}
|
||||
|
||||
append(" ")
|
||||
@@ -463,7 +465,20 @@ private fun HelpUsImprove(
|
||||
)
|
||||
|
||||
Text(
|
||||
text = stringResource(R.string.CallQualitySheet__debug_log_privacy_notice),
|
||||
text = buildAnnotatedString {
|
||||
append(stringResource(R.string.CallQualitySheet__information_shared_with_us))
|
||||
append(" ")
|
||||
|
||||
withLink(
|
||||
link = LinkAnnotation.Clickable(
|
||||
"view-debug-log",
|
||||
linkInteractionListener = { onViewDebugLogClick() },
|
||||
styles = TextLinkStyles(style = SpanStyle(color = MaterialTheme.colorScheme.primary))
|
||||
)
|
||||
) {
|
||||
append(stringResource(R.string.CallQualitySheet__view_debug_log))
|
||||
}
|
||||
},
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier
|
||||
@@ -688,6 +703,7 @@ private fun HelpUsImprovePreview() {
|
||||
Column {
|
||||
HelpUsImprove(
|
||||
isShareDebugLogSelected = true,
|
||||
onViewDiagnosticsClick = {},
|
||||
onViewDebugLogClick = {},
|
||||
onCancelClick = {},
|
||||
onShareDebugLogChanged = {},
|
||||
@@ -728,6 +744,7 @@ data class CallQualitySheetState(
|
||||
interface CallQualitySheetCallback {
|
||||
fun dismiss()
|
||||
fun viewDebugLog()
|
||||
fun viewDiagnostics()
|
||||
fun onUserSatisfiedWithCall(isUserSatisfiedWithCall: Boolean)
|
||||
fun describeYourIssue()
|
||||
fun onCallQualityIssueSelectionChanged(selection: Set<CallQualityIssue>)
|
||||
@@ -738,6 +755,7 @@ interface CallQualitySheetCallback {
|
||||
object Empty : CallQualitySheetCallback {
|
||||
override fun dismiss() = Unit
|
||||
override fun viewDebugLog() = Unit
|
||||
override fun viewDiagnostics() = Unit
|
||||
override fun onUserSatisfiedWithCall(isUserSatisfiedWithCall: Boolean) = Unit
|
||||
override fun describeYourIssue() = Unit
|
||||
override fun onCallQualityIssueSelectionChanged(selection: Set<CallQualityIssue>) = Unit
|
||||
|
||||
@@ -2705,6 +2705,12 @@
|
||||
<!-- Content description for the button that switches between front and back camera during a call -->
|
||||
<string name="SwitchCameraButton__switch_camera_direction">Switch camera direction</string>
|
||||
|
||||
<!-- CallQualityDiagnosticsScreen -->
|
||||
<!-- Title for the call quality diagnostics screen -->
|
||||
<string name="CallQualityDiagnosticsScreen__diagnostic_information">Diagnostic information</string>
|
||||
<!-- Content description for the close/back navigation button -->
|
||||
<string name="CallQualityDiagnosticsScreen__close">Close</string>
|
||||
|
||||
<!-- CallToastPopupWindow -->
|
||||
<string name="CallToastPopupWindow__swipe_to_view_screen_share">Swipe to view screen share</string>
|
||||
|
||||
@@ -9037,11 +9043,15 @@
|
||||
<!-- Title asking user to help improve Signal -->
|
||||
<string name="CallQualitySheet__help_us_improve">Help us improve</string>
|
||||
<!-- First part of description explaining diagnostics help improve call quality -->
|
||||
<string name="CallQualitySheet__help_us_improve_description_prefix">Sending us your diagnostics info helps us improve call quality. You can </string>
|
||||
<string name="CallQualitySheet__help_us_improve_description_prefix">Submitting will share your feedback along with</string>
|
||||
<!-- Clickable text to launch diagnostic fragment -->
|
||||
<string name="CallQualitySheet__diagnostic_information_about_your_call">diagnostic information about your call</string>
|
||||
<!-- End of description explaining diagnostics help improve call quality -->
|
||||
<string name="CallQualitySheet__help_us_improve_description_suffix">You can optionally share a debug log to help us improve call quality.</string>
|
||||
<!-- Text explaining the debug log -->
|
||||
<string name="CallQualitySheet__information_shared_with_us">Information shared with us contains low level app information and does not include the contents of your calls.</string>
|
||||
<!-- Link text to view debug log -->
|
||||
<string name="CallQualitySheet__view_your_debug_log">view your debug log</string>
|
||||
<!-- Last part of description about viewing debug log before submitting -->
|
||||
<string name="CallQualitySheet__help_us_improve_description_suffix"> before submitting.</string>
|
||||
<string name="CallQualitySheet__view_debug_log">View debug log</string>
|
||||
<!-- Toggle label for sharing debug log -->
|
||||
<string name="CallQualitySheet__share_debug_log">Share debug log</string>
|
||||
<!-- Privacy notice explaining what debug logs contain and why they are helpful -->
|
||||
|
||||
Reference in New Issue
Block a user