Merge pull request #7323 from vector-im/feature/mna/device-manager-parsing-os
[Device management] Improve the parsing for OS of Desktop/Web sessions (PSG-823)
This commit is contained in:
commit
f9eb6a64ea
|
@ -0,0 +1 @@
|
|||
[Device management] Improve the parsing for OS of Desktop/Web sessions
|
|
@ -74,55 +74,77 @@ class ParseDeviceUserAgentUseCase @Inject constructor() {
|
|||
}
|
||||
|
||||
private fun parseDesktopUserAgent(userAgent: String): DeviceExtendedInfo {
|
||||
val browserInfo = parseBrowserInfoFromDesktopUserAgent(userAgent)
|
||||
val operatingSystem = parseOperatingSystemFromDesktopUserAgent(userAgent)
|
||||
|
||||
return DeviceExtendedInfo(
|
||||
deviceType = DeviceType.DESKTOP,
|
||||
deviceModel = null,
|
||||
deviceOperatingSystem = operatingSystem,
|
||||
clientName = browserInfo.name,
|
||||
clientVersion = browserInfo.version,
|
||||
)
|
||||
}
|
||||
|
||||
private data class BrowserInfo(val name: String? = null, val version: String? = null)
|
||||
|
||||
private fun parseBrowserInfoFromDesktopUserAgent(userAgent: String): BrowserInfo {
|
||||
val browserSegments = userAgent.split(" ")
|
||||
val (browserName, browserVersion) = when {
|
||||
return when {
|
||||
isFirefox(browserSegments) -> {
|
||||
Pair("Firefox", getBrowserVersion(browserSegments, "Firefox"))
|
||||
BrowserInfo(BROWSER_FIREFOX, getBrowserVersion(browserSegments, BROWSER_FIREFOX))
|
||||
}
|
||||
isEdge(browserSegments) -> {
|
||||
Pair("Edge", getBrowserVersion(browserSegments, "Edge"))
|
||||
BrowserInfo(BROWSER_EDGE, getBrowserVersion(browserSegments, BROWSER_EDGE))
|
||||
}
|
||||
isMobile(browserSegments) -> {
|
||||
when (val name = getMobileBrowserName(browserSegments)) {
|
||||
null -> {
|
||||
Pair(null, null)
|
||||
BrowserInfo()
|
||||
}
|
||||
"Safari" -> {
|
||||
Pair(name, getBrowserVersion(browserSegments, "Version"))
|
||||
BROWSER_SAFARI -> {
|
||||
BrowserInfo(name, getBrowserVersion(browserSegments, "Version"))
|
||||
}
|
||||
else -> {
|
||||
Pair(name, getBrowserVersion(browserSegments, name))
|
||||
BrowserInfo(name, getBrowserVersion(browserSegments, name))
|
||||
}
|
||||
}
|
||||
}
|
||||
isSafari(browserSegments) -> {
|
||||
Pair("Safari", getBrowserVersion(browserSegments, "Version"))
|
||||
BrowserInfo(BROWSER_SAFARI, getBrowserVersion(browserSegments, "Version"))
|
||||
}
|
||||
else -> {
|
||||
when (val name = getRegularBrowserName(browserSegments)) {
|
||||
null -> {
|
||||
Pair(null, null)
|
||||
BrowserInfo()
|
||||
}
|
||||
else -> {
|
||||
Pair(name, getBrowserVersion(browserSegments, name))
|
||||
BrowserInfo(name, getBrowserVersion(browserSegments, name))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val deviceOperatingSystemSegments = userAgent.substringAfter("(").substringBefore(")").split("; ")
|
||||
val deviceOperatingSystem = if (deviceOperatingSystemSegments.getOrNull(1)?.startsWith("Android").orFalse()) {
|
||||
deviceOperatingSystemSegments.getOrNull(1)
|
||||
} else {
|
||||
deviceOperatingSystemSegments.getOrNull(0)
|
||||
private fun parseOperatingSystemFromDesktopUserAgent(userAgent: String): String? {
|
||||
val deviceOperatingSystemSegments = userAgent
|
||||
.substringAfter("(")
|
||||
.substringBefore(")")
|
||||
.split("; ")
|
||||
val firstSegment = deviceOperatingSystemSegments.getOrNull(0).orEmpty()
|
||||
val secondSegment = deviceOperatingSystemSegments.getOrNull(1).orEmpty()
|
||||
|
||||
return when {
|
||||
// e.g. (Macintosh; Intel Mac OS X 10_15_7) => macOS
|
||||
firstSegment.startsWith(OPERATING_SYSTEM_MAC_KEYWORD) -> OPERATING_SYSTEM_MAC
|
||||
// e.g. (Windows NT 10.0; Win64; x64) => Windows
|
||||
firstSegment.startsWith(OPERATING_SYSTEM_WINDOWS_KEYWORD) -> OPERATING_SYSTEM_WINDOWS_KEYWORD
|
||||
// e.g. (iPad; CPU OS 8_4_1 like Mac OS X) => iOS
|
||||
firstSegment.startsWith(DEVICE_IPAD_KEYWORD) || firstSegment.startsWith(DEVICE_IPHONE_KEYWORD) -> OPERATING_SYSTEM_IOS
|
||||
// e.g. (Linux; Android 9; SM-G973U Build/PPR1.180610.011) => Android
|
||||
secondSegment.startsWith(OPERATING_SYSTEM_ANDROID_KEYWORD) -> OPERATING_SYSTEM_ANDROID_KEYWORD
|
||||
else -> null
|
||||
}
|
||||
return DeviceExtendedInfo(
|
||||
deviceType = DeviceType.DESKTOP,
|
||||
deviceModel = null,
|
||||
deviceOperatingSystem = deviceOperatingSystem,
|
||||
clientName = browserName,
|
||||
clientVersion = browserVersion,
|
||||
)
|
||||
}
|
||||
|
||||
private fun parseWebUserAgent(userAgent: String): DeviceExtendedInfo {
|
||||
|
@ -136,7 +158,7 @@ class ParseDeviceUserAgentUseCase @Inject constructor() {
|
|||
}
|
||||
|
||||
private fun isFirefox(browserSegments: List<String>): Boolean {
|
||||
return browserSegments.lastOrNull()?.startsWith("Firefox").orFalse()
|
||||
return browserSegments.lastOrNull()?.startsWith(BROWSER_FIREFOX).orFalse()
|
||||
}
|
||||
|
||||
private fun getBrowserVersion(browserSegments: List<String>, browserName: String): String? {
|
||||
|
@ -148,11 +170,11 @@ class ParseDeviceUserAgentUseCase @Inject constructor() {
|
|||
}
|
||||
|
||||
private fun isEdge(browserSegments: List<String>): Boolean {
|
||||
return browserSegments.lastOrNull()?.startsWith("Edge").orFalse()
|
||||
return browserSegments.lastOrNull()?.startsWith(BROWSER_EDGE).orFalse()
|
||||
}
|
||||
|
||||
private fun isSafari(browserSegments: List<String>): Boolean {
|
||||
return browserSegments.lastOrNull()?.startsWith("Safari").orFalse() &&
|
||||
return browserSegments.lastOrNull()?.startsWith(BROWSER_SAFARI).orFalse() &&
|
||||
browserSegments.getOrNull(browserSegments.size - 2)?.startsWith("Version").orFalse()
|
||||
}
|
||||
|
||||
|
@ -163,7 +185,7 @@ class ParseDeviceUserAgentUseCase @Inject constructor() {
|
|||
private fun getMobileBrowserName(browserSegments: List<String>): String? {
|
||||
val possibleBrowserName = browserSegments.getOrNull(browserSegments.size - 3)?.split("/")?.firstOrNull()
|
||||
return if (possibleBrowserName == "Version") {
|
||||
"Safari"
|
||||
BROWSER_SAFARI
|
||||
} else {
|
||||
possibleBrowserName
|
||||
}
|
||||
|
@ -187,5 +209,17 @@ 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
|
||||
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"
|
||||
|
||||
private const val BROWSER_FIREFOX = "Firefox"
|
||||
private const val BROWSER_SAFARI = "Safari"
|
||||
private const val BROWSER_EDGE = "Edge"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
)
|
||||
private val AN_EXPECTED_RESULT_LIST_FOR_DESKTOP = listOf(
|
||||
DeviceExtendedInfo(DeviceType.DESKTOP, null, "Macintosh", "Electron", "20.1.1"),
|
||||
DeviceExtendedInfo(DeviceType.DESKTOP, null, "Windows NT 10.0", "Electron", "20.1.1"),
|
||||
DeviceExtendedInfo(DeviceType.DESKTOP, null, "macOS", "Electron", "20.1.1"),
|
||||
DeviceExtendedInfo(DeviceType.DESKTOP, null, "Windows", "Electron", "20.1.1"),
|
||||
)
|
||||
|
||||
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",
|
||||
)
|
||||
private val AN_EXPECTED_RESULT_LIST_FOR_WEB = listOf(
|
||||
DeviceExtendedInfo(DeviceType.WEB, null, "Macintosh", "Chrome", "104.0.5112.102"),
|
||||
DeviceExtendedInfo(DeviceType.WEB, null, "Windows NT 10.0", "Chrome", "104.0.5112.102"),
|
||||
DeviceExtendedInfo(DeviceType.WEB, null, "Macintosh", "Firefox", "39.0"),
|
||||
DeviceExtendedInfo(DeviceType.WEB, null, "Macintosh", "Safari", "8.0.3"),
|
||||
DeviceExtendedInfo(DeviceType.WEB, null, "Android 9", "Chrome", "69.0.3497.100"),
|
||||
DeviceExtendedInfo(DeviceType.WEB, null, "iPad", "Safari", "8.0"),
|
||||
DeviceExtendedInfo(DeviceType.WEB, null, "iPhone", "Safari", "8.0"),
|
||||
DeviceExtendedInfo(DeviceType.WEB, null, "Windows NT 6.0", "Firefox", "40.0"),
|
||||
DeviceExtendedInfo(DeviceType.WEB, null, "Windows NT 10.0", "Edge", "12.246"),
|
||||
DeviceExtendedInfo(DeviceType.WEB, null, "macOS", "Chrome", "104.0.5112.102"),
|
||||
DeviceExtendedInfo(DeviceType.WEB, null, "Windows", "Chrome", "104.0.5112.102"),
|
||||
DeviceExtendedInfo(DeviceType.WEB, null, "macOS", "Firefox", "39.0"),
|
||||
DeviceExtendedInfo(DeviceType.WEB, null, "macOS", "Safari", "8.0.3"),
|
||||
DeviceExtendedInfo(DeviceType.WEB, null, "Android", "Chrome", "69.0.3497.100"),
|
||||
DeviceExtendedInfo(DeviceType.WEB, null, "iOS", "Safari", "8.0"),
|
||||
DeviceExtendedInfo(DeviceType.WEB, null, "iOS", "Safari", "8.0"),
|
||||
DeviceExtendedInfo(DeviceType.WEB, null, "Windows", "Firefox", "40.0"),
|
||||
DeviceExtendedInfo(DeviceType.WEB, null, "Windows", "Edge", "12.246"),
|
||||
)
|
||||
|
||||
private val AN_UNKNOWN_USER_AGENT_LIST = listOf(
|
||||
|
|
Loading…
Reference in New Issue