]> source.dussan.org Git - vaadin-framework.git/commitdiff
Functions for reporting Android and iOS version (#8716)
authorArtur Signell <artur.signell@itmill.com>
Thu, 26 Apr 2012 13:11:45 +0000 (13:11 +0000)
committerArtur Signell <artur.signell@itmill.com>
Thu, 26 Apr 2012 13:11:45 +0000 (13:11 +0000)
svn changeset:23642/svn branch:6.8

src/com/vaadin/terminal/gwt/client/BrowserInfo.java
src/com/vaadin/terminal/gwt/client/VBrowserDetails.java
tests/client-side/com/vaadin/terminal/gwt/client/TestVBrowserDetailsUserAgentParser.java

index a2e5bffe39ccde4bc98b6017addf91980565669a..8ec610c089d90b4fa7e7c52dac9f13900d48a24d 100644 (file)
@@ -456,4 +456,19 @@ public class BrowserInfo {
         return false;
     }
 
+    /**
+     * Tests if this is an Android devices with a broken scrollTop
+     * implementation
+     * 
+     * @return true if scrollTop cannot be trusted on this device, false
+     *         otherwise
+     */
+    public boolean isAndroidWithBrokenScrollTop() {
+        return isAndroid()
+                && (getOperatingSystemMajorVersion() == 3 || getOperatingSystemMajorVersion() == 4);
+    }
+
+    private int getOperatingSystemMajorVersion() {
+        return browserDetails.getOperatingSystemMajorVersion();
+    }
 }
index fa5fdc6d476b97b18db347a46f6e06aa2beda22b..1212447a6528f74822ddbb7072b6cb04264e510b 100644 (file)
@@ -38,6 +38,9 @@ public class VBrowserDetails implements Serializable {
     private int browserMajorVersion = -1;
     private int browserMinorVersion = -1;
 
+    private int osMajorVersion = -1;
+    private int osMinorVersion = -1;
+
     /**
      * Create an instance based on the given user agent.
      * 
@@ -121,6 +124,7 @@ public class VBrowserDetails implements Serializable {
         } else if (userAgent.contains("linux")) {
             if (userAgent.contains("android")) {
                 os = OperatingSystem.ANDROID;
+                parseAndroidVersion(userAgent);
             } else {
                 os = OperatingSystem.LINUX;
 
@@ -131,12 +135,67 @@ public class VBrowserDetails implements Serializable {
             if (userAgent.contains("ipad") || userAgent.contains("ipod")
                     || userAgent.contains("iphone")) {
                 os = OperatingSystem.IOS;
+                parseIOSVersion(userAgent);
             } else {
                 os = OperatingSystem.MACOSX;
             }
         }
     }
 
+    private void parseAndroidVersion(String userAgent) {
+        // Android 5.1;
+        if (!userAgent.contains("android")) {
+            return;
+        }
+
+        String osVersionString = safeSubstring(userAgent,
+                userAgent.indexOf("android ") + "android ".length(),
+                userAgent.length());
+        osVersionString = safeSubstring(osVersionString, 0,
+                osVersionString.indexOf(";"));
+        String[] parts = osVersionString.split("\\.");
+        parseOsVersion(parts);
+    }
+
+    private void parseIOSVersion(String userAgent) {
+        // OS 5_1 like Mac OS X
+        if (!userAgent.contains("os ") || !userAgent.contains(" like mac")) {
+            return;
+        }
+
+        String osVersionString = safeSubstring(userAgent,
+                userAgent.indexOf("os ") + 3, userAgent.indexOf(" like mac"));
+        String[] parts = osVersionString.split("_");
+        parseOsVersion(parts);
+    }
+
+    private void parseOsVersion(String[] parts) {
+        osMajorVersion = -1;
+        osMinorVersion = -1;
+
+        if (parts.length >= 1) {
+            try {
+                osMajorVersion = Integer.parseInt(parts[0]);
+            } catch (Exception e) {
+            }
+        }
+        if (parts.length >= 2) {
+            try {
+                osMinorVersion = Integer.parseInt(parts[1]);
+            } catch (Exception e) {
+            }
+            // Some Androids report version numbers as "2.1-update1"
+            if (osMinorVersion == -1 && parts[1].contains("-")) {
+                try {
+                    osMinorVersion = Integer.parseInt(parts[1].substring(0,
+                            parts[1].indexOf('-')));
+                } catch (Exception ee) {
+                }
+            }
+        }
+
+    }
+
     private void parseVersionString(String versionString) {
         int idx = versionString.indexOf('.');
         if (idx < 0) {
@@ -332,4 +391,24 @@ public class VBrowserDetails implements Serializable {
         return os == OperatingSystem.IOS;
     }
 
+    /**
+     * Returns the major version of the operating system. Currently only
+     * supported for mobile devices (iOS/Android)
+     * 
+     * @return The major version or -1 if unknown
+     */
+    public int getOperatingSystemMajorVersion() {
+        return osMajorVersion;
+    }
+
+    /**
+     * Returns the minor version of the operating system. Currently only
+     * supported for mobile devices (iOS/Android)
+     * 
+     * @return The minor version or -1 if unknown
+     */
+    public int getOperatingSystemMinorVersion() {
+        return osMinorVersion;
+    }
+
 }
index 98159775bdbcab5cd2bdfcb537debaae08b0f943..fedce98ecf1ca3ff443b7d1285ea9978a09e1657 100644 (file)
@@ -36,8 +36,14 @@ public class TestVBrowserDetailsUserAgentParser extends TestCase {
     private static final String SAFARI4_MAC = "Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_5_8; en-us) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7";
 
     private static final String IPHONE_IOS_5_1 = "Mozilla/5.0 (iPhone; CPU iPhone OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B179 Safari/7534.48.3";
+    private static final String IPHONE_IOS_4_0 = "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7";
     private static final String IPAD_IOS_4_3_1 = "Mozilla/5.0 (iPad; U; CPU OS 4_3_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8G4 Safari/6533.18.5";
 
+    private static final String ANDROID_HTC_2_1 = "Mozilla/5.0 (Linux; U; Android 2.1-update1; en-us; ADR6300 Build/ERE27) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17";
+    private static final String ANDROID_GOOGLE_NEXUS_2_2 = "Mozilla/5.0 (Linux; U; Android 2.2; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1";
+    private static final String ANDROID_MOTOROLA_3_0 = "Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13";
+    private static final String ANDROID_GALAXY_NEXUS_4_0_4_CHROME = "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19";
+
     public void testSafari3() {
         VBrowserDetails bd = new VBrowserDetails(SAFARI3_WINDOWS);
         assertWebKit(bd);
@@ -65,8 +71,17 @@ public class TestVBrowserDetailsUserAgentParser extends TestCase {
         assertBrowserMajorVersion(bd, 5);
         assertBrowserMinorVersion(bd, 1);
         assertEngineVersion(bd, 534f);
-        assertMacOSX(bd);
-        assertIOS(bd);
+        assertIOS(bd, 5, 1);
+    }
+
+    public void testIPhoneIOS4() {
+        VBrowserDetails bd = new VBrowserDetails(IPHONE_IOS_4_0);
+        assertWebKit(bd);
+        assertSafari(bd);
+        assertBrowserMajorVersion(bd, 4);
+        assertBrowserMinorVersion(bd, 0);
+        assertEngineVersion(bd, 532f);
+        assertIOS(bd, 4, 0);
     }
 
     public void testIPadIOS4() {
@@ -76,8 +91,57 @@ public class TestVBrowserDetailsUserAgentParser extends TestCase {
         assertBrowserMajorVersion(bd, 5);
         assertBrowserMinorVersion(bd, 0);
         assertEngineVersion(bd, 533f);
-        assertMacOSX(bd);
-        assertIOS(bd);
+        assertIOS(bd, 4, 3);
+    }
+
+    public void testAndroid21() {
+        VBrowserDetails bd = new VBrowserDetails(ANDROID_HTC_2_1);
+        assertWebKit(bd);
+        assertSafari(bd);
+        assertBrowserMajorVersion(bd, 4);
+        assertBrowserMinorVersion(bd, 0);
+        assertEngineVersion(bd, 530f);
+        assertAndroid(bd, 2, 1);
+
+    }
+
+    public void testAndroid22() {
+        VBrowserDetails bd = new VBrowserDetails(ANDROID_GOOGLE_NEXUS_2_2);
+        assertWebKit(bd);
+        assertSafari(bd);
+        assertBrowserMajorVersion(bd, 4);
+        assertBrowserMinorVersion(bd, 0);
+        assertEngineVersion(bd, 533f);
+        assertAndroid(bd, 2, 2);
+    }
+
+    public void testAndroid30() {
+        VBrowserDetails bd = new VBrowserDetails(ANDROID_MOTOROLA_3_0);
+        assertWebKit(bd);
+        assertSafari(bd);
+        assertBrowserMajorVersion(bd, 4);
+        assertBrowserMinorVersion(bd, 0);
+        assertEngineVersion(bd, 534f);
+        assertAndroid(bd, 3, 0);
+    }
+
+    public void testAndroid40Chrome() {
+        VBrowserDetails bd = new VBrowserDetails(
+                ANDROID_GALAXY_NEXUS_4_0_4_CHROME);
+        assertWebKit(bd);
+        assertChrome(bd);
+        assertBrowserMajorVersion(bd, 18);
+        assertBrowserMinorVersion(bd, 0);
+        assertEngineVersion(bd, 535f);
+        assertAndroid(bd, 4, 0);
+    }
+
+    private void assertOSMajorVersion(VBrowserDetails bd, int i) {
+        assertEquals(i, bd.getOperatingSystemMajorVersion());
+    }
+
+    private void assertOSMinorVersion(VBrowserDetails bd, int i) {
+        assertEquals(i, bd.getOperatingSystemMinorVersion());
     }
 
     public void testChrome3() {
@@ -378,12 +442,28 @@ public class TestVBrowserDetailsUserAgentParser extends TestCase {
         assertFalse(browserDetails.isAndroid());
     }
 
-    private void assertIOS(VBrowserDetails browserDetails) {
+    private void assertAndroid(VBrowserDetails browserDetails,
+            int majorVersion, int minorVersion) {
         assertFalse(browserDetails.isLinux());
         assertFalse(browserDetails.isWindows());
-        assertTrue(browserDetails.isMacOSX());
+        assertFalse(browserDetails.isMacOSX());
+        assertFalse(browserDetails.isIOS());
+        assertTrue(browserDetails.isAndroid());
+
+        assertOSMajorVersion(browserDetails, majorVersion);
+        assertOSMinorVersion(browserDetails, minorVersion);
+    }
+
+    private void assertIOS(VBrowserDetails browserDetails, int majorVersion,
+            int minorVersion) {
+        assertFalse(browserDetails.isLinux());
+        assertFalse(browserDetails.isWindows());
+        assertFalse(browserDetails.isMacOSX());
         assertTrue(browserDetails.isIOS());
         assertFalse(browserDetails.isAndroid());
+
+        assertOSMajorVersion(browserDetails, majorVersion);
+        assertOSMinorVersion(browserDetails, minorVersion);
     }
 
     private void assertWindows(VBrowserDetails browserDetails) {
@@ -399,6 +479,7 @@ public class TestVBrowserDetailsUserAgentParser extends TestCase {
         assertFalse(browserDetails.isWindows());
         assertFalse(browserDetails.isMacOSX());
         assertFalse(browserDetails.isIOS());
+        assertFalse(browserDetails.isAndroid());
     }
 
 }