From 410965ddca3e601343f8b759e1a27a2c1b0d0f29 Mon Sep 17 00:00:00 2001 From: Flamenco Date: Thu, 27 Jul 2017 06:24:43 -0400 Subject: [PATCH] Add support for detecting ChromeOS operating system (#9698) --- .../VBrowserDetailsUserAgentParserTest.java | 27 ++++++++++ .../java/com/vaadin/server/WebBrowser.java | 10 ++++ .../com/vaadin/shared/VBrowserDetails.java | 54 ++++++++++++++++++- 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/client/src/test/java/com/vaadin/client/VBrowserDetailsUserAgentParserTest.java b/client/src/test/java/com/vaadin/client/VBrowserDetailsUserAgentParserTest.java index bc4b7d1524..2594b3d09d 100644 --- a/client/src/test/java/com/vaadin/client/VBrowserDetailsUserAgentParserTest.java +++ b/client/src/test/java/com/vaadin/client/VBrowserDetailsUserAgentParserTest.java @@ -57,6 +57,8 @@ public class VBrowserDetailsUserAgentParserTest { private static final String PHANTOMJS_211_MAC = "Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/538.1 (KHTML, like Gecko) PhantomJS/2.1.1 Safari/538.1"; private static final String CHROME_57_ON_IOS_10_3_1 = "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/57.0.2987.137 Mobile/14E304 Safari/602.1"; + private static final String CHROME_40_ON_CHROMEOS = "Mozilla/5.0 (X11; CrOS x86_64 6457.31.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.38 Safari/537.36"; + @Test public void testSafari3() { VBrowserDetails bd = new VBrowserDetails(SAFARI3_WINDOWS); @@ -205,6 +207,17 @@ public class VBrowserDetailsUserAgentParserTest { assertWindows(bd); } + @Test + public void testChromeChromeOS() { + VBrowserDetails bd = new VBrowserDetails(CHROME_40_ON_CHROMEOS); + assertWebKit(bd); + assertChrome(bd); + assertBrowserMajorVersion(bd, 40); + assertBrowserMinorVersion(bd, 0); + assertEngineVersion(bd, 537f); + assertChromeOS(bd); + } + @Test public void testChromeIOS() { VBrowserDetails bd = new VBrowserDetails(CHROME_57_ON_IOS_10_3_1); @@ -570,6 +583,7 @@ public class VBrowserDetailsUserAgentParserTest { assertFalse(browserDetails.isWindows()); assertTrue(browserDetails.isMacOSX()); assertFalse(browserDetails.isAndroid()); + assertFalse(browserDetails.isChromeOS()); } private void assertAndroid(VBrowserDetails browserDetails, int majorVersion, @@ -579,6 +593,7 @@ public class VBrowserDetailsUserAgentParserTest { assertFalse(browserDetails.isMacOSX()); assertFalse(browserDetails.isIOS()); assertTrue(browserDetails.isAndroid()); + assertFalse(browserDetails.isChromeOS()); assertOSMajorVersion(browserDetails, majorVersion); assertOSMinorVersion(browserDetails, minorVersion); @@ -591,6 +606,7 @@ public class VBrowserDetailsUserAgentParserTest { assertFalse(browserDetails.isMacOSX()); assertTrue(browserDetails.isIOS()); assertFalse(browserDetails.isAndroid()); + assertFalse(browserDetails.isChromeOS()); assertOSMajorVersion(browserDetails, majorVersion); assertOSMinorVersion(browserDetails, minorVersion); @@ -617,6 +633,7 @@ public class VBrowserDetailsUserAgentParserTest { assertFalse(browserDetails.isMacOSX()); assertFalse(browserDetails.isIOS()); assertFalse(browserDetails.isAndroid()); + assertFalse(browserDetails.isChromeOS()); Assert.assertEquals(isWindowsPhone, browserDetails.isWindowsPhone()); } @@ -626,6 +643,16 @@ public class VBrowserDetailsUserAgentParserTest { assertFalse(browserDetails.isMacOSX()); assertFalse(browserDetails.isIOS()); assertFalse(browserDetails.isAndroid()); + assertFalse(browserDetails.isChromeOS()); + } + + private void assertChromeOS(VBrowserDetails browserDetails) { + assertFalse(browserDetails.isLinux()); + assertFalse(browserDetails.isWindows()); + assertFalse(browserDetails.isMacOSX()); + assertFalse(browserDetails.isIOS()); + assertFalse(browserDetails.isAndroid()); + assertTrue(browserDetails.isChromeOS()); } } diff --git a/server/src/main/java/com/vaadin/server/WebBrowser.java b/server/src/main/java/com/vaadin/server/WebBrowser.java index 82f5e2df79..b454da030c 100644 --- a/server/src/main/java/com/vaadin/server/WebBrowser.java +++ b/server/src/main/java/com/vaadin/server/WebBrowser.java @@ -329,6 +329,16 @@ public class WebBrowser implements Serializable { return browserDetails.isIPad(); } + /** + * Tests if the browser is run on ChromeOS (e.g. a Chromebook). + * + * @return true if run on ChromeOS false if the user is not using ChromeOS or if no + * information on the browser is present + */ + public boolean isChromeOS() { + return browserDetails.isChromeOS(); + } + /** * Returns the browser-reported TimeZone offset in milliseconds from GMT. * This includes possible daylight saving adjustments, to figure out which diff --git a/shared/src/main/java/com/vaadin/shared/VBrowserDetails.java b/shared/src/main/java/com/vaadin/shared/VBrowserDetails.java index fdf9b5f723..17a7cafff2 100644 --- a/shared/src/main/java/com/vaadin/shared/VBrowserDetails.java +++ b/shared/src/main/java/com/vaadin/shared/VBrowserDetails.java @@ -47,11 +47,12 @@ public class VBrowserDetails implements Serializable { private boolean isWindowsPhone; private boolean isIPad; private boolean isIPhone; + private boolean isChromeOS; private OperatingSystem os = OperatingSystem.UNKNOWN; public enum OperatingSystem { - UNKNOWN, WINDOWS, MACOSX, LINUX, IOS, ANDROID; + UNKNOWN, WINDOWS, MACOSX, LINUX, IOS, ANDROID, CHROMEOS; } private float browserEngineVersion = -1; @@ -217,9 +218,51 @@ public class VBrowserDetails implements Serializable { } else { os = OperatingSystem.MACOSX; } + } else if (userAgent.contains("; cros ")){ + os = OperatingSystem.CHROMEOS; + isChromeOS = true; + parseChromeOSVersion(userAgent); } } + // (X11; CrOS armv7l 6946.63.0) + private void parseChromeOSVersion(String userAgent) { + int start = userAgent.indexOf("; cros "); + if (start == -1) { + return; + } + int end = userAgent.indexOf(')', start); + if (end == -1) { + return; + } + int cur = end; + while (cur >= start && userAgent.charAt(cur) != ' ') { + cur--; + } + if (cur == start) { + return; + } + String osVersionString = userAgent.substring(cur + 1, end); + String[] parts = osVersionString.split("\\."); + parseChromeOsVersion(parts); + } + + private void parseChromeOsVersion(String[] parts) { + osMajorVersion = -1; + osMinorVersion = -1; + + if (parts.length > 2) { + try { + osMajorVersion = Integer.parseInt(parts[1]); + } catch (Exception e) { + } + try { + osMinorVersion = Integer.parseInt(parts[0]); + } catch (Exception e) { + } + } + } + private void parseAndroidVersion(String userAgent) { // Android 5.1; if (!userAgent.contains("android")) { @@ -558,6 +601,15 @@ public class VBrowserDetails implements Serializable { return isIPad; } + /** + * Tests if the browser is run on Chrome OS (e.g. a Chromebook). + * + * @return true if run on Chrome OS, false otherwise + */ + public boolean isChromeOS() { + return isChromeOS; + } + /** * Returns the major version of the operating system. Currently only * supported for mobile devices (iOS/Android) -- 2.39.5