mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-20 02:58:45 +00:00
Update call quality string.
This commit is contained in:
@@ -10,6 +10,7 @@ import org.signal.ringrtc.CallSummary
|
|||||||
import org.signal.ringrtc.GroupCall
|
import org.signal.ringrtc.GroupCall
|
||||||
import org.signal.storageservice.protos.calls.quality.SubmitCallQualitySurveyRequest
|
import org.signal.storageservice.protos.calls.quality.SubmitCallQualitySurveyRequest
|
||||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||||
|
import org.thoughtcrime.securesms.util.LocaleRemoteConfig
|
||||||
import org.thoughtcrime.securesms.util.RemoteConfig
|
import org.thoughtcrime.securesms.util.RemoteConfig
|
||||||
import kotlin.time.Duration.Companion.days
|
import kotlin.time.Duration.Companion.days
|
||||||
import kotlin.time.Duration.Companion.milliseconds
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
@@ -71,10 +72,19 @@ object CallQuality {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Consumes any pending request. We will automatically filter out requests if they're over five minutes old.
|
||||||
|
*/
|
||||||
fun consumeQualityRequest(): SubmitCallQualitySurveyRequest? {
|
fun consumeQualityRequest(): SubmitCallQualitySurveyRequest? {
|
||||||
val request = SignalStore.callQuality.surveyRequest
|
val request = SignalStore.callQuality.surveyRequest ?: return null
|
||||||
SignalStore.callQuality.surveyRequest = null
|
SignalStore.callQuality.surveyRequest = null
|
||||||
return if (isFeatureEnabled()) request else null
|
|
||||||
|
val fiveMinutesAgo = System.currentTimeMillis().milliseconds - 5.minutes
|
||||||
|
return if (!isFeatureEnabled() || request.end_timestamp.milliseconds < fiveMinutesAgo) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
request
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isCallQualitySurveyRequired(callSummary: CallSummary): Boolean {
|
private fun isCallQualitySurveyRequired(callSummary: CallSummary): Boolean {
|
||||||
@@ -109,8 +119,8 @@ object CallQuality {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
val chance = RemoteConfig.callQualitySurveyPercent
|
val chance = LocaleRemoteConfig.getCallQualitySurveyPartsPerMillion()
|
||||||
val roll = (0 until 100).random()
|
val roll = (0 until 1_000_000).random()
|
||||||
|
|
||||||
if (roll < chance) {
|
if (roll < chance) {
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -82,6 +82,10 @@ public final class LocaleRemoteConfig {
|
|||||||
return isEnabledPartsPerMillion(RemoteConfig.DEVICE_SPECIFIC_NOTIFICATION_CONFIG, DeviceSpecificNotificationConfig.getCurrentConfig().getLocalePercent());
|
return isEnabledPartsPerMillion(RemoteConfig.DEVICE_SPECIFIC_NOTIFICATION_CONFIG, DeviceSpecificNotificationConfig.getCurrentConfig().getLocalePercent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static long getCallQualitySurveyPartsPerMillion() {
|
||||||
|
return getPartsPerMillion(RemoteConfig.callQualitySurveyPPM());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a comma-separated list of country codes and area codes to check if self's e164 starts with
|
* Parses a comma-separated list of country codes and area codes to check if self's e164 starts with
|
||||||
* one of them. For example, "33,1555" will return turn for e164's that start with 33 or look like 1-555-xxx-xxx.
|
* one of them. For example, "33,1555" will return turn for e164's that start with 33 or look like 1-555-xxx-xxx.
|
||||||
@@ -104,6 +108,17 @@ public final class LocaleRemoteConfig {
|
|||||||
return countryAndAreaCodes.stream().anyMatch(e164Numbers::startsWith);
|
return countryAndAreaCodes.stream().anyMatch(e164Numbers::startsWith);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static long getPartsPerMillion(@NonNull String serialized) {
|
||||||
|
Map<String, Integer> countryCodeValues = parseCountryValues(serialized, 0);
|
||||||
|
Recipient self = Recipient.self();
|
||||||
|
|
||||||
|
if (countryCodeValues.isEmpty() || !self.getE164().isPresent() || !self.getServiceId().isPresent()) {
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getCountryValue(countryCodeValues, self.getE164().orElse(""), 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a comma-separated list of country codes colon-separated from how many buckets out of 1 million
|
* Parses a comma-separated list of country codes colon-separated from how many buckets out of 1 million
|
||||||
* should be enabled to see this megaphone in that country code. At the end of the list, an optional
|
* should be enabled to see this megaphone in that country code. At the end of the list, an optional
|
||||||
@@ -112,14 +127,8 @@ public final class LocaleRemoteConfig {
|
|||||||
* the world should see the megaphone.
|
* the world should see the megaphone.
|
||||||
*/
|
*/
|
||||||
private static boolean isEnabledPartsPerMillion(@NonNull String flag, @NonNull String serialized) {
|
private static boolean isEnabledPartsPerMillion(@NonNull String flag, @NonNull String serialized) {
|
||||||
Map<String, Integer> countryCodeValues = parseCountryValues(serialized, 0);
|
|
||||||
Recipient self = Recipient.self();
|
Recipient self = Recipient.self();
|
||||||
|
long countEnabled = getPartsPerMillion(serialized);
|
||||||
if (countryCodeValues.isEmpty() || !self.getE164().isPresent() || !self.getServiceId().isPresent()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
long countEnabled = getCountryValue(countryCodeValues, self.getE164().orElse(""), 0);
|
|
||||||
long currentUserBucket = BucketingUtil.bucket(flag, self.requireAci().getRawUuid(), 1_000_000);
|
long currentUserBucket = BucketingUtil.bucket(flag, self.requireAci().getRawUuid(), 1_000_000);
|
||||||
|
|
||||||
return countEnabled > currentUserBucket;
|
return countEnabled > currentUserBucket;
|
||||||
|
|||||||
@@ -1226,16 +1226,16 @@ object RemoteConfig {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
@get:JvmName("callQualitySurvey")
|
@get:JvmName("callQualitySurvey")
|
||||||
val callQualitySurvey: Boolean by remoteBoolean(
|
val callQualitySurvey: Boolean by remoteBoolean(
|
||||||
key = "android.callQualitySurvey.3",
|
key = "android.callQualitySurvey.4",
|
||||||
defaultValue = false,
|
defaultValue = false,
|
||||||
hotSwappable = true
|
hotSwappable = true
|
||||||
)
|
)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@get:JvmName("callQualitySurveyPercent")
|
@get:JvmName("callQualitySurveyPPM")
|
||||||
val callQualitySurveyPercent: Int by remoteInt(
|
val callQualitySurveyPPM: String by remoteString(
|
||||||
key = "android.callQualitySurveyPercent",
|
key = "android.callQualitySurveyPPM",
|
||||||
defaultValue = 1,
|
defaultValue = "*:10000",
|
||||||
hotSwappable = true
|
hotSwappable = true
|
||||||
)
|
)
|
||||||
// endregion
|
// endregion
|
||||||
|
|||||||
@@ -79,5 +79,4 @@ public class LocaleRemoteConfigTest_getCountryValue {
|
|||||||
public void determineCountEnabled() {
|
public void determineCountEnabled() {
|
||||||
assertEquals(output, LocaleRemoteConfig.getCountryValue(countryCounts, phoneNumber, 0));
|
assertEquals(output, LocaleRemoteConfig.getCountryValue(countryCounts, phoneNumber, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user