Fixing parsing of operating system info for Desktop/Web user agent

This commit is contained in:
Maxime NATUREL 2022-10-10 14:31:52 +02:00
parent 4e70fcd339
commit b4cd72e009
2 changed files with 59 additions and 15 deletions

View file

@ -127,11 +127,47 @@ class ParseDeviceUserAgentUseCase @Inject constructor() {
} }
private fun parseOperatingSystemFromDesktopUserAgent(userAgent: String): String? { private fun parseOperatingSystemFromDesktopUserAgent(userAgent: String): String? {
val deviceOperatingSystemSegments = userAgent.substringAfter("(").substringBefore(")").split("; ") val deviceOperatingSystemSegments = userAgent
return if (deviceOperatingSystemSegments.getOrNull(1)?.startsWith("Android").orFalse()) { .substringAfter("(")
deviceOperatingSystemSegments.getOrNull(1) .substringBefore(")")
.split("; ")
val firstSegment = deviceOperatingSystemSegments.getOrNull(0).orEmpty()
val secondSegment = deviceOperatingSystemSegments.getOrNull(1).orEmpty()
return when {
firstSegment.startsWith(OPERATING_SYSTEM_MAC_KEYWORD) -> {
// e.g. (Macintosh; Intel Mac OS X 10_15_7) => macOS 10.15.7
val version = secondSegment
.substringAfterLast(" ")
.replace("_", ".")
if (version.isEmpty()) {
OPERATING_SYSTEM_MAC
} else { } else {
deviceOperatingSystemSegments.getOrNull(0) "$OPERATING_SYSTEM_MAC $version"
}
}
firstSegment.startsWith(OPERATING_SYSTEM_WINDOWS_KEYWORD) -> {
// e.g. (Windows NT 10.0; Win64; x64) => Windows 10.0
firstSegment.replace("NT ", "")
}
firstSegment.startsWith(DEVICE_IPAD_KEYWORD) || firstSegment.startsWith(DEVICE_IPHONE_KEYWORD) -> {
// e.g. (iPad; CPU OS 8_4_1 like Mac OS X) => macOS 8.4.1
val version = secondSegment
.split(" ")
.find { it.contains("_") }
?.replace("_", ".")
.orEmpty()
if (version.isEmpty()) {
OPERATING_SYSTEM_IOS
} else {
"$OPERATING_SYSTEM_IOS $version"
}
}
secondSegment.startsWith(OPERATING_SYSTEM_ANDROID_KEYWORD) -> {
// e.g. (Linux; Android 9; SM-G973U Build/PPR1.180610.011) => Android 9
secondSegment
}
else -> null
} }
} }
@ -197,5 +233,13 @@ class ParseDeviceUserAgentUseCase @Inject constructor() {
// Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 // Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36
private const val WEB_KEYWORD = "Mozilla/" private const val WEB_KEYWORD = "Mozilla/"
private const val OPERATING_SYSTEM_MAC_KEYWORD = "Macintosh"
private const val OPERATING_SYSTEM_MAC = "macOS"
private const val OPERATING_SYSTEM_IOS = "iOS"
private const val OPERATING_SYSTEM_WINDOWS_KEYWORD = "Windows"
private const val OPERATING_SYSTEM_ANDROID_KEYWORD = "Android"
private const val DEVICE_IPAD_KEYWORD = "iPad"
private const val DEVICE_IPHONE_KEYWORD = "iPhone"
} }
} }

View file

@ -62,8 +62,8 @@ private val A_USER_AGENT_LIST_FOR_DESKTOP = listOf(
"Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) ElementNightly/2022091301 Chrome/104.0.5112.102 Electron/20.1.1 Safari/537.36", "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) ElementNightly/2022091301 Chrome/104.0.5112.102 Electron/20.1.1 Safari/537.36",
) )
private val AN_EXPECTED_RESULT_LIST_FOR_DESKTOP = listOf( private val AN_EXPECTED_RESULT_LIST_FOR_DESKTOP = listOf(
DeviceExtendedInfo(DeviceType.DESKTOP, null, "Macintosh", "Electron", "20.1.1"), DeviceExtendedInfo(DeviceType.DESKTOP, null, "macOS 10.15.7", "Electron", "20.1.1"),
DeviceExtendedInfo(DeviceType.DESKTOP, null, "Windows NT 10.0", "Electron", "20.1.1"), DeviceExtendedInfo(DeviceType.DESKTOP, null, "Windows 10.0", "Electron", "20.1.1"),
) )
private val A_USER_AGENT_LIST_FOR_WEB = listOf( private val A_USER_AGENT_LIST_FOR_WEB = listOf(
@ -78,15 +78,15 @@ private val A_USER_AGENT_LIST_FOR_WEB = listOf(
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246",
) )
private val AN_EXPECTED_RESULT_LIST_FOR_WEB = listOf( private val AN_EXPECTED_RESULT_LIST_FOR_WEB = listOf(
DeviceExtendedInfo(DeviceType.WEB, null, "Macintosh", "Chrome", "104.0.5112.102"), DeviceExtendedInfo(DeviceType.WEB, null, "macOS 10.15.7", "Chrome", "104.0.5112.102"),
DeviceExtendedInfo(DeviceType.WEB, null, "Windows NT 10.0", "Chrome", "104.0.5112.102"), DeviceExtendedInfo(DeviceType.WEB, null, "Windows 10.0", "Chrome", "104.0.5112.102"),
DeviceExtendedInfo(DeviceType.WEB, null, "Macintosh", "Firefox", "39.0"), DeviceExtendedInfo(DeviceType.WEB, null, "macOS 10.10", "Firefox", "39.0"),
DeviceExtendedInfo(DeviceType.WEB, null, "Macintosh", "Safari", "8.0.3"), DeviceExtendedInfo(DeviceType.WEB, null, "macOS 10.10.2", "Safari", "8.0.3"),
DeviceExtendedInfo(DeviceType.WEB, null, "Android 9", "Chrome", "69.0.3497.100"), DeviceExtendedInfo(DeviceType.WEB, null, "Android 9", "Chrome", "69.0.3497.100"),
DeviceExtendedInfo(DeviceType.WEB, null, "iPad", "Safari", "8.0"), DeviceExtendedInfo(DeviceType.WEB, null, "iOS 8.4.1", "Safari", "8.0"),
DeviceExtendedInfo(DeviceType.WEB, null, "iPhone", "Safari", "8.0"), DeviceExtendedInfo(DeviceType.WEB, null, "iOS 8.4.1", "Safari", "8.0"),
DeviceExtendedInfo(DeviceType.WEB, null, "Windows NT 6.0", "Firefox", "40.0"), DeviceExtendedInfo(DeviceType.WEB, null, "Windows 6.0", "Firefox", "40.0"),
DeviceExtendedInfo(DeviceType.WEB, null, "Windows NT 10.0", "Edge", "12.246"), DeviceExtendedInfo(DeviceType.WEB, null, "Windows 10.0", "Edge", "12.246"),
) )
private val AN_UNKNOWN_USER_AGENT_LIST = listOf( private val AN_UNKNOWN_USER_AGENT_LIST = listOf(