diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/DeviceSpecificNotificationConfig.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/DeviceSpecificNotificationConfig.kt index c882399c0b..d31ed0d093 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/DeviceSpecificNotificationConfig.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/DeviceSpecificNotificationConfig.kt @@ -29,6 +29,7 @@ object DeviceSpecificNotificationConfig { */ data class Config( @JsonProperty val model: String = "", + @JsonProperty val manufacturer: String = "", @JsonProperty val showConditionCode: String = ShowCondition.NONE.code, @JsonProperty val link: String = GENERAL_SUPPORT_URL, @JsonProperty val localePercent: String = "*", @@ -66,16 +67,27 @@ object DeviceSpecificNotificationConfig { emptyList() } - val config: Config? = list - .filter { it.model.isNotEmpty() } - .find { - if (it.model.last() == '*') { - Build.MODEL.startsWith(it.model.substring(0, it.model.length - 1)) - } else { - it.model.contains(Build.MODEL) - } - } + val matchedConfigs: List = list + .filter { matchesModel(it.model) || matchesManufacturer(it.manufacturer) } - return config ?: default + val matchedModelConfig: Config? = matchedConfigs.firstOrNull { matchesModel(it.model) } + + if (matchedModelConfig != null) { + return matchedModelConfig + } + + return matchedConfigs.firstOrNull() ?: default + } + + private fun matchesModel(model: String): Boolean { + return if (model.isNotEmpty() && model.last() == '*') { + Build.MODEL.startsWith(model.substring(0, model.length - 1)) + } else { + model.equals(Build.MODEL, ignoreCase = true) + } + } + + private fun matchesManufacturer(manufacturer: String): Boolean { + return manufacturer.equals(Build.MANUFACTURER, ignoreCase = true) } } diff --git a/app/src/test/java/org/thoughtcrime/securesms/notifications/DeviceSpecificNotificationConfigTest.kt b/app/src/test/java/org/thoughtcrime/securesms/notifications/DeviceSpecificNotificationConfigTest.kt index a2f1bf1f2d..168d7fd8f8 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/notifications/DeviceSpecificNotificationConfigTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/notifications/DeviceSpecificNotificationConfigTest.kt @@ -97,4 +97,31 @@ class DeviceSpecificNotificationConfigTest { every { RemoteConfig.deviceSpecificNotificationConfig } returns """[ { "model": "test" } ]""" DeviceSpecificNotificationConfig.computeConfig() assertIs DeviceSpecificNotificationConfig.Config(model = "test", localePercent = "*", version = 0) } + + @Test + fun `manufacturer match`() { + ReflectionHelpers.setStaticField(Build::class.java, "MODEL", "test-model") + ReflectionHelpers.setStaticField(Build::class.java, "MANUFACTURER", "test-manufacturer") + every { RemoteConfig.deviceSpecificNotificationConfig } returns + """ + [ + { "manufacturer": "test-manufacturer", "showConditionCode": "always", "localePercent": "*:10000", "version": 1 } + ] + """.trimMargin() + DeviceSpecificNotificationConfig.computeConfig() assertIs DeviceSpecificNotificationConfig.Config(manufacturer = "test-manufacturer", showConditionCode = "always", localePercent = "*:10000", version = 1) + } + + @Test + fun `device model is matched over device manufacturer`() { + ReflectionHelpers.setStaticField(Build::class.java, "MODEL", "test-model") + ReflectionHelpers.setStaticField(Build::class.java, "MANUFACTURER", "test-manufacturer") + every { RemoteConfig.deviceSpecificNotificationConfig } returns + """ + [ + { "manufacturer": "test-manufacturer", "showConditionCode": "always", "localePercent": "*:10000", "version": 1 }, + { "model": "test-model", "showConditionCode": "has-battery-optimization-on", "localePercent": "*:20000", "version": 2 } + ] + """.trimMargin() + DeviceSpecificNotificationConfig.computeConfig() assertIs DeviceSpecificNotificationConfig.Config(model = "test-model", showConditionCode = "has-battery-optimization-on", localePercent = "*:20000", version = 2) + } }