From 1d28c3194e9240b5c80e64bf12f474eb3e835312 Mon Sep 17 00:00:00 2001 From: Ryan Bennitt Date: Mon, 16 Jul 2018 11:15:12 +0100 Subject: [PATCH] Fix iPhone and Android detection on Windows phones. Mavenised java project and added unit tests. --- .../Sub-Classed Page Technique/MDetectPage.cs | 10 +- .../UserControl Technique/MDetectControl.cs | 10 +- Cpp/mdetect.h | 9 +- Java/pom.xml | 42 ++ .../handinteractive/mobile}/UAgentInfo.java | 31 +- .../mobile/UAgentInfoTest.java | 419 ++++++++++++++++++ JavaScript/mdetect.js | 9 +- PHP/mdetect.php | 9 +- Python/mdetect.py | 11 +- 9 files changed, 515 insertions(+), 35 deletions(-) create mode 100644 Java/pom.xml rename Java/{ => src/main/java/com/handinteractive/mobile}/UAgentInfo.java (95%) create mode 100644 Java/src/test/java/com/handinteractive/mobile/UAgentInfoTest.java diff --git a/ASP_NET/Sub-Classed Page Technique/MDetectPage.cs b/ASP_NET/Sub-Classed Page Technique/MDetectPage.cs index 581b428..462db0f 100755 --- a/ASP_NET/Sub-Classed Page Technique/MDetectPage.cs +++ b/ASP_NET/Sub-Classed Page Technique/MDetectPage.cs @@ -558,8 +558,8 @@ public bool DetectIphone() { if (useragent.IndexOf(deviceIphone)!= -1) { - //The iPad and iPod touch say they're an iPhone! So let's disambiguate. - if (DetectIpad() || DetectIpod()) + //The iPad, iPod Touch and Windows Phone 8 say they're an iPhone! So let's disambiguate. + if (DetectIpad() || DetectIpod() || DetectWindowsPhone8()) { return false; } @@ -608,8 +608,10 @@ public bool DetectIos() // Also detects Google TV. public bool DetectAndroid() { - if ((useragent.IndexOf(deviceAndroid) != -1) || - DetectGoogleTV()) + if (((useragent.IndexOf(deviceAndroid) != -1) + && !DetectWindowsPhone10() + && !DetectWindowsPhone8()) + || DetectGoogleTV()) return true; return false; diff --git a/ASP_NET/UserControl Technique/MDetectControl.cs b/ASP_NET/UserControl Technique/MDetectControl.cs index edc93b4..723d33f 100755 --- a/ASP_NET/UserControl Technique/MDetectControl.cs +++ b/ASP_NET/UserControl Technique/MDetectControl.cs @@ -534,8 +534,8 @@ public bool DetectIphone() { if (useragent.IndexOf(deviceIphone)!= -1) { - //The iPad and iPod touch say they're an iPhone! So let's disambiguate. - if (DetectIpad() || DetectIpod()) + //The iPad, iPod Touch and Windows Phone 8 say they're an iPhone! So let's disambiguate. + if (DetectIpad() || DetectIpod() || DetectWindowsPhone8()) { return false; } @@ -615,8 +615,10 @@ public bool DetectIos() // Also detects Google TV. public bool DetectAndroid() { - if ((useragent.IndexOf(deviceAndroid) != -1) || - DetectGoogleTV()) + if (((useragent.IndexOf(deviceAndroid) != -1) + && !DetectWindowsPhone10() + && !DetectWindowsPhone8()) + || DetectGoogleTV()) return true; return false; diff --git a/Cpp/mdetect.h b/Cpp/mdetect.h index 92f22fe..b7b7ee6 100755 --- a/Cpp/mdetect.h +++ b/Cpp/mdetect.h @@ -294,9 +294,10 @@ class uagent_info if (useragent.find( MobileESP::deviceIphone) != std::string::npos) { - //The iPad and iPod Touch say they're an iPhone. So let's disambiguate. + //The iPad, iPod Touch and Windows Phone 8 say they're an iPhone. So let's disambiguate. if (DetectIpad() == true || - DetectIpod() == true) + DetectIpod() == true || + DetectWindowsPhone8() == true) return false; //Yay! It's an iPhone! else @@ -360,7 +361,9 @@ class uagent_info isAndroid == true) return isAndroid; - if ((useragent.find( MobileESP::deviceAndroid) != std::string::npos) + if (((useragent.find( MobileESP::deviceAndroid) != std::string::npos) + && (DetectWindowsPhone10() == false) + && (DetectWindowsPhone10() == false)) || (DetectGoogleTV() == true)) return true; diff --git a/Java/pom.xml b/Java/pom.xml new file mode 100644 index 0000000..d339fdb --- /dev/null +++ b/Java/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + + com.handinteractive.mobile + MobileESP + 1.0-SNAPSHOT + + + UTF-8 + 1.8 + 1.8 + + + + junit + junit + 4.12 + test + + + org.hamcrest + hamcrest-all + 1.3 + test + + + org.apache.maven.plugins + maven-resources-plugin + 3.1.0 + test + + + com.google.code.gson + gson + 2.8.5 + test + + + \ No newline at end of file diff --git a/Java/UAgentInfo.java b/Java/src/main/java/com/handinteractive/mobile/UAgentInfo.java similarity index 95% rename from Java/UAgentInfo.java rename to Java/src/main/java/com/handinteractive/mobile/UAgentInfo.java index e4dd0f7..a978296 100755 --- a/Java/UAgentInfo.java +++ b/Java/src/main/java/com/handinteractive/mobile/UAgentInfo.java @@ -306,10 +306,11 @@ public void initDeviceScan() { * @return detection of an iPhone */ public boolean detectIphone() { - // The iPad and iPod touch say they're an iPhone! So let's disambiguate. - if (userAgent.indexOf(deviceIphone) != -1 && + // The iPad, iPod Touch and Windows Phone 8 say they're an iPhone! So let's disambiguate. + if (userAgent.indexOf(deviceIphone) != -1 && !detectIpad() && - !detectIpod()) { + !detectIpod() && + !detectWindowsPhone8()) { return true; } return false; @@ -344,7 +345,8 @@ && detectWebkit()) { */ public boolean detectIphoneOrIpod() { //We repeat the searches here because some iPods may report themselves as an iPhone, which would be okay. - if (userAgent.indexOf(deviceIphone) != -1 + if ((userAgent.indexOf(deviceIphone) != -1 + && !detectWindowsPhone8()) || userAgent.indexOf(deviceIpod) != -1) { return true; } @@ -369,8 +371,10 @@ public boolean detectIos() { * @return detection of an Android device */ public boolean detectAndroid() { - if ((userAgent.indexOf(deviceAndroid) != -1) || - detectGoogleTV()) + if ((userAgent.indexOf(deviceAndroid) != -1 + && !detectWindowsPhone10() + && !detectWindowsPhone8()) + || detectGoogleTV()) return true; return false; @@ -414,7 +418,7 @@ public boolean detectAndroidTablet() { return false; //Otherwise, if it's Android and does NOT have 'mobile' in it, Google says it's a tablet. - if ((userAgent.indexOf(mobile) > -1)) + if ((userAgent.indexOf(mobile) > -1)) return false; else return true; @@ -546,10 +550,9 @@ public boolean detectWindowsMobile() { // and some older ones report as 'PIE' for Pocket IE. // We also look for instances of HTC and Windows for many of their WinMo devices. if (userAgent.indexOf(deviceWinMob) != -1 - || userAgent.indexOf(deviceWinMob) != -1 || userAgent.indexOf(deviceIeMob) != -1 || userAgent.indexOf(enginePie) != -1 - || (userAgent.indexOf(manuHtc) != -1 && userAgent.indexOf(deviceWindows) != -1) + || (userAgent.indexOf(manuHtc) != -1 && userAgent.indexOf(deviceWindows) != -1) || (detectWapWml() && userAgent.indexOf(deviceWindows) != -1)) { return true; } @@ -568,8 +571,8 @@ public boolean detectWindowsMobile() { * @return detection of Blackberry */ public boolean detectBlackBerry() { - if (userAgent.indexOf(deviceBB) != -1 || - httpAccept.indexOf(vndRIM) != -1) + if (userAgent.indexOf(deviceBB) != -1 || + httpAccept.indexOf(vndRIM) != -1) return true; if (detectBlackBerry10Phone()) @@ -584,7 +587,7 @@ public boolean detectBlackBerry() { * @return detection of a Blackberry 10 device */ public boolean detectBlackBerry10Phone() { - if (userAgent.indexOf(deviceBB10) != -1 && + if (userAgent.indexOf(deviceBB10) != -1 && userAgent.indexOf(mobile) != -1) { return true; } @@ -714,7 +717,7 @@ public boolean detectPalmWebOS() { * @return detection of an HP WebOS tablet */ public boolean detectWebOSTablet() { - if (userAgent.indexOf(deviceWebOShp) != -1 && + if (userAgent.indexOf(deviceWebOShp) != -1 && userAgent.indexOf(deviceTablet) != -1) { return true; } @@ -726,7 +729,7 @@ public boolean detectWebOSTablet() { * @return detection of a WebOS smart TV */ public boolean detectWebOSTV() { - if (userAgent.indexOf(deviceWebOStv) != -1 && + if (userAgent.indexOf(deviceWebOStv) != -1 && userAgent.indexOf(smartTV2) != -1) { return true; } diff --git a/Java/src/test/java/com/handinteractive/mobile/UAgentInfoTest.java b/Java/src/test/java/com/handinteractive/mobile/UAgentInfoTest.java new file mode 100644 index 0000000..e897028 --- /dev/null +++ b/Java/src/test/java/com/handinteractive/mobile/UAgentInfoTest.java @@ -0,0 +1,419 @@ +package com.handinteractive.mobile; + +import org.junit.Test; + +import static org.hamcrest.Matchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +public class UAgentInfoTest { + + @Test + public void shouldDetectChromeAndroidMobile() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (Linux; Android 8.1.0; Nexus 5X Build/OPM3.171019.013) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36", null); + + assertThat(uAgentInfo.detectAndroidPhone(), is(true)); + assertThat(uAgentInfo.detectAndroidTablet(), is(false)); + assertIsNotAnyIDevice(uAgentInfo); + assertIsNotAnyWindowsDevice(uAgentInfo); + + assertIsMobileDevice(uAgentInfo); + + assertThat(uAgentInfo.detectAndroid(), is(true)); + + assertIsWebkit(uAgentInfo); + } + + @Test + public void shouldDetectFirefoxAndroidMobile() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (Android 7.0; Mobile; rv:57.0) Gecko/57.0 Firefox/57.0", null); + + assertThat(uAgentInfo.detectAndroidPhone(), is(true)); + assertThat(uAgentInfo.detectAndroidTablet(), is(false)); + assertIsNotAnyIDevice(uAgentInfo); + assertIsNotAnyWindowsDevice(uAgentInfo); + + assertIsMobileDevice(uAgentInfo); + + assertThat(uAgentInfo.detectAndroid(), is(true)); + + assertIsNotWebkitNorRichCss(uAgentInfo); + } + + @Test + public void shouldDetectAndroidBrowserMobile() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (Linux; U; Android 4.4.4; en-gb; SM-G357FZ Build/KTU84P) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", null); + + assertThat(uAgentInfo.detectAndroidPhone(), is(true)); + assertThat(uAgentInfo.detectAndroidTablet(), is(false)); + assertIsNotAnyIDevice(uAgentInfo); + assertIsNotAnyWindowsDevice(uAgentInfo); + + assertIsMobileDevice(uAgentInfo); + + assertThat(uAgentInfo.detectAndroid(), is(true)); + + assertIsWebkit(uAgentInfo); + } + + @Test + public void shouldDetectChromeAndroidTablet() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (Linux; Android 8.0.0; Pixel C Build/OPR1.170623.027) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Safari/537.36", null); + + assertThat(uAgentInfo.detectAndroidTablet(), is(true)); + assertThat(uAgentInfo.detectAndroidPhone(), is(false)); + assertIsNotAnyIDevice(uAgentInfo); + assertIsNotAnyWindowsDevice(uAgentInfo); + + assertIsTabletDevice(uAgentInfo); + + assertThat(uAgentInfo.detectAndroid(), is(true)); + + assertIsWebkit(uAgentInfo); + } + + @Test + public void shouldDetectFirefoxAndroidTablet() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (Android 7.0; Tablet; rv:57.0) Gecko/57.0 Firefox/57.0", null); + + assertThat(uAgentInfo.detectAndroidTablet(), is(true)); + assertThat(uAgentInfo.detectAndroidPhone(), is(false)); + assertIsNotAnyIDevice(uAgentInfo); + assertIsNotAnyWindowsDevice(uAgentInfo); + + assertIsTabletDevice(uAgentInfo); + + assertThat(uAgentInfo.detectAndroid(), is(true)); + + assertIsNotWebkitNorRichCss(uAgentInfo); + } + + @Test + public void shouldDetectAndroidBrowserTablet() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (Linux; U; Android 4.4.2; en-gb; SM-T310 Build/KOT49H) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", null); + + assertThat(uAgentInfo.detectAndroidTablet(), is(true)); + assertThat(uAgentInfo.detectAndroidPhone(), is(false)); + assertIsNotAnyIDevice(uAgentInfo); + assertIsNotAnyWindowsDevice(uAgentInfo); + + assertIsTabletDevice(uAgentInfo); + + assertThat(uAgentInfo.detectAndroid(), is(true)); + + assertIsWebkit(uAgentInfo); + } + + @Test + public void shouldNotDetectChromeOS() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (X11; CrOS x86_64 10032.75.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.116 Safari/537.36", null); + + assertIsNotAnyIDevice(uAgentInfo); + assertIsNotAnyAndroidDevice(uAgentInfo); + assertIsNotAnyWindowsDevice(uAgentInfo); + + assertIsNotSupportedDevice(uAgentInfo); + + assertIsWebkit(uAgentInfo); + } + + @Test + public void shouldDetectBlackberryMobile() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.1.0.346 Mobile Safari/534.11+", null); + + assertThat(uAgentInfo.detectBlackBerry(), is(true)); + assertThat(uAgentInfo.detectBlackBerry10Phone(), is(false)); + assertThat(uAgentInfo.detectBlackBerryHigh(), is(false)); + assertThat(uAgentInfo.detectBlackBerryTouch(), is(true)); + assertThat(uAgentInfo.detectBlackBerryTablet(), is(false)); + assertThat(uAgentInfo.detectBlackBerryLow(), is(false)); + assertIsNotAnyIDevice(uAgentInfo); + assertIsNotAnyAndroidDevice(uAgentInfo); + assertIsNotAnyWindowsDevice(uAgentInfo); + + assertIsMobileDevice(uAgentInfo); + + assertThat(uAgentInfo.detectBlackBerryWebKit(), is(true)); + assertIsWebkit(uAgentInfo); + } + + @Test + public void shouldDetectSafariIPad() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (iPad; CPU OS 11_2_5 like Mac OS X) AppleWebKit/604.5.3 (KHTML, like Gecko) Version/11.0 Mobile/15D5049a Safari/604.1", null); + + assertThat(uAgentInfo.detectIpad(), is(true)); + assertThat(uAgentInfo.detectIpod(), is(false)); + assertThat(uAgentInfo.getIsIphone(), is(false)); + assertThat(uAgentInfo.detectIphoneOrIpod(), is(false)); + assertIsNotAnyAndroidDevice(uAgentInfo); + assertIsNotAnyWindowsDevice(uAgentInfo); + + assertIsTabletDevice(uAgentInfo); + + assertThat(uAgentInfo.detectIos(), is(true)); + + assertIsWebkit(uAgentInfo); + } + + @Test + public void shouldDetectSafariIPhone() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (iPhone; CPU iPhone OS 11_2_5 like Mac OS X) AppleWebKit/604.5.3 (KHTML, like Gecko) Version/11.0 Mobile/15D5049a Safari/604.1", null); + + assertThat(uAgentInfo.getIsIphone(), is(true)); + assertThat(uAgentInfo.detectIpod(), is(false)); + assertThat(uAgentInfo.detectIpad(), is(false)); + assertThat(uAgentInfo.detectIphoneOrIpod(), is(true)); + assertIsNotAnyAndroidDevice(uAgentInfo); + assertIsNotAnyWindowsDevice(uAgentInfo); + + assertIsMobileDevice(uAgentInfo); + + assertThat(uAgentInfo.detectIos(), is(true)); + + assertIsWebkit(uAgentInfo); + } + + @Test + public void shouldDetectSafariIpod() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (iPod touch; CPU iPhone OS 11_1_2 like Mac OS X) AppleWebKit/604.3.5 (KHTML, like Gecko) Version/11.0 Mobile/15B202 Safari/604.1", null); + + assertThat(uAgentInfo.detectIpod(), is(true)); + assertThat(uAgentInfo.getIsIphone(), is(false)); + assertThat(uAgentInfo.detectIpad(), is(false)); + assertThat(uAgentInfo.detectIphoneOrIpod(), is(true)); + assertIsNotAnyAndroidDevice(uAgentInfo); + assertIsNotAnyWindowsDevice(uAgentInfo); + + assertIsMobileDevice(uAgentInfo); + + assertThat(uAgentInfo.detectIos(), is(true)); + + assertIsWebkit(uAgentInfo); + } + + @Test + public void shouldNotDetectSafariMacintosh() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8", null); + + assertIsNotAnyIDevice(uAgentInfo); + assertIsNotAnyAndroidDevice(uAgentInfo); + assertIsNotAnyWindowsDevice(uAgentInfo); + + assertIsNotSupportedDevice(uAgentInfo); + + assertIsWebkit(uAgentInfo); + } + + @Test + public void shouldNotDetectChromeMacintosh() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36", null); + + assertIsNotAnyIDevice(uAgentInfo); + assertIsNotAnyAndroidDevice(uAgentInfo); + assertIsNotAnyWindowsDevice(uAgentInfo); + + assertIsNotSupportedDevice(uAgentInfo); + + assertIsWebkit(uAgentInfo); + } + + @Test + public void shouldNotDetectFirefoxMacintosh() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:57.0) Gecko/20100101 Firefox/57.0", null); + + assertIsNotAnyIDevice(uAgentInfo); + assertIsNotAnyAndroidDevice(uAgentInfo); + assertIsNotAnyWindowsDevice(uAgentInfo); + + assertIsNotSupportedDevice(uAgentInfo); + + assertIsNotWebkitNorRichCss(uAgentInfo); + } + + @Test + public void shouldDetectEdgeWindowsPhone() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (Windows Phone 10.0; Android 6.0.1; Microsoft; Lumia 640 LTE) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Mobile Safari/537.36 Edge/15.15063", null); + + assertThat(uAgentInfo.detectWindowsPhone10(), is(true)); + assertThat(uAgentInfo.detectWindowsPhone8(), is(false)); + assertThat(uAgentInfo.detectWindowsPhone7(), is(false)); + assertThat(uAgentInfo.detectWindowsMobile(), is(false)); + assertIsNotAnyIDevice(uAgentInfo); + assertIsNotAnyAndroidDevice(uAgentInfo); + + assertIsMobileDevice(uAgentInfo); + + assertThat(uAgentInfo.detectWindowsPhone(), is(true)); + + assertIsWebkit(uAgentInfo); + } + + @Test + public void shouldDetectInternetExplorerWindowsPhone() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; Microsoft; Lumia 640 LTE) like iPhone OS 7_0_3 Mac OS X AppleWebKit/537 (KHTML, like Gecko) Mobile Safari/537", null); + + assertThat(uAgentInfo.detectWindowsPhone8(), is(true)); + assertThat(uAgentInfo.detectWindowsPhone7(), is(false)); + assertThat(uAgentInfo.detectWindowsPhone10(), is(false)); + assertThat(uAgentInfo.detectWindowsMobile(), is(false)); + assertIsNotAnyIDevice(uAgentInfo); + assertIsNotAnyAndroidDevice(uAgentInfo); + + assertIsMobileDevice(uAgentInfo); + + assertThat(uAgentInfo.detectWindowsPhone(), is(true)); + + assertIsWebkit(uAgentInfo); + } + + @Test + public void shouldNotDetectInternetExplorerWindows() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko", null); + + assertIsNotAnyIDevice(uAgentInfo); + assertIsNotAnyAndroidDevice(uAgentInfo); + assertIsNotAnyWindowsDevice(uAgentInfo); + + assertIsNotSupportedDevice(uAgentInfo); + + assertIsNotWebkitNorRichCss(uAgentInfo); + } + + @Test + public void shouldNotDetectEdgeWindows() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299", null); + + assertIsNotAnyIDevice(uAgentInfo); + assertIsNotAnyAndroidDevice(uAgentInfo); + assertIsNotAnyWindowsDevice(uAgentInfo); + + assertIsNotSupportedDevice(uAgentInfo); + + assertIsWebkit(uAgentInfo); + } + + @Test + public void shouldNotDetectChromeWindows() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.71 Safari/537.36", null); + + assertIsNotAnyIDevice(uAgentInfo); + assertIsNotAnyAndroidDevice(uAgentInfo); + assertIsNotAnyWindowsDevice(uAgentInfo); + + assertIsNotSupportedDevice(uAgentInfo); + + assertIsWebkit(uAgentInfo); + } + + @Test + public void shouldNotDetectFirefoxWindows() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0", null); + + assertIsNotAnyIDevice(uAgentInfo); + assertIsNotAnyAndroidDevice(uAgentInfo); + assertIsNotAnyWindowsDevice(uAgentInfo); + + assertIsNotSupportedDevice(uAgentInfo); + + assertIsNotWebkitNorRichCss(uAgentInfo); + } + + @Test + public void shouldNotDetectFirefoxUbuntu() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0", null); + + assertThat(uAgentInfo.detectUbuntu(), is(false)); + assertIsNotAnyIDevice(uAgentInfo); + assertIsNotAnyAndroidDevice(uAgentInfo); + assertIsNotAnyWindowsDevice(uAgentInfo); + + assertIsNotSupportedDevice(uAgentInfo); + + assertIsNotWebkitNorRichCss(uAgentInfo); + } + + @Test + public void shouldDetectFirefoxLinux() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (X11; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0", null); + + assertIsNotAnyIDevice(uAgentInfo); + assertIsNotAnyAndroidDevice(uAgentInfo); + assertIsNotAnyWindowsDevice(uAgentInfo); + + assertIsNotSupportedDevice(uAgentInfo); + + assertIsNotWebkitNorRichCss(uAgentInfo); + } + + @Test + public void shouldDetectOperaWindows() { + UAgentInfo uAgentInfo = new UAgentInfo("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36 OPR/50.0.2762.45", null); + + assertIsNotAnyIDevice(uAgentInfo); + assertIsNotAnyAndroidDevice(uAgentInfo); + assertIsNotAnyWindowsDevice(uAgentInfo); + + assertIsNotSupportedDevice(uAgentInfo); + + assertIsWebkit(uAgentInfo); + } + + private void assertIsNotAnyIDevice(UAgentInfo uAgentInfo) { + assertThat(uAgentInfo.detectIpod(), is(false)); + assertThat(uAgentInfo.getIsIphone(), is(false)); + assertThat(uAgentInfo.detectIpad(), is(false)); + assertThat(uAgentInfo.detectIphoneOrIpod(), is(false)); + assertThat(uAgentInfo.detectIos(), is(false)); + } + + private void assertIsNotAnyAndroidDevice(UAgentInfo uAgentInfo) { + assertThat(uAgentInfo.detectAndroid(), is(false)); + assertThat(uAgentInfo.detectAndroidPhone(), is(false)); + assertThat(uAgentInfo.detectAndroidTablet(), is(false)); + assertThat(uAgentInfo.detectAndroidWebKit(), is(false)); + } + + private void assertIsNotAnyWindowsDevice(UAgentInfo uAgentInfo) { + assertThat(uAgentInfo.detectWindowsPhone10(), is(false)); + assertThat(uAgentInfo.detectWindowsPhone8(), is(false)); + assertThat(uAgentInfo.detectWindowsPhone7(), is(false)); + assertThat(uAgentInfo.detectWindowsMobile(), is(false)); + assertThat(uAgentInfo.detectWindowsPhone(), is(false)); + } + + private void assertIsNotSupportedDevice(UAgentInfo uAgentInfo) { + assertThat(uAgentInfo.detectMobileQuick(), is(false)); + assertThat(uAgentInfo.detectMobileLong(), is(false)); + assertThat(uAgentInfo.getIsTierIphone(), is(false)); + assertThat(uAgentInfo.getIsTierTablet(), is(false)); + assertThat(uAgentInfo.detectGameConsole(), is(false)); + assertThat(uAgentInfo.getIsTierGenericMobile(), is(false)); + } + + private void assertIsMobileDevice(UAgentInfo uAgentInfo) { + assertThat(uAgentInfo.detectMobileQuick(), is(true)); + assertThat(uAgentInfo.detectMobileLong(), is(true)); + assertThat(uAgentInfo.getIsTierIphone(), is(true)); + assertThat(uAgentInfo.getIsTierTablet(), is(false)); + assertThat(uAgentInfo.detectGameConsole(), is(false)); + assertThat(uAgentInfo.getIsTierGenericMobile(), is(false)); + } + + private void assertIsTabletDevice(UAgentInfo uAgentInfo) { + assertThat(uAgentInfo.getIsTierTablet(), is(true)); + assertThat(uAgentInfo.detectMobileQuick(), is(false)); + assertThat(uAgentInfo.detectMobileLong(), is(false)); + assertThat(uAgentInfo.getIsTierIphone(), is(false)); + assertThat(uAgentInfo.detectGameConsole(), is(false)); + assertThat(uAgentInfo.getIsTierGenericMobile(), is(false)); + } + + private void assertIsWebkit(UAgentInfo uAgentInfo) { + assertThat(uAgentInfo.detectWebkit(), is(true)); + assertThat(uAgentInfo.getIsTierRichCss(), is(false)); + } + + private void assertIsNotWebkitNorRichCss(UAgentInfo uAgentInfo) { + assertThat(uAgentInfo.detectWebkit(), is(false)); + assertThat(uAgentInfo.getIsTierRichCss(), is(false)); + } +} \ No newline at end of file diff --git a/JavaScript/mdetect.js b/JavaScript/mdetect.js index d7a3a13..258ace1 100755 --- a/JavaScript/mdetect.js +++ b/JavaScript/mdetect.js @@ -259,8 +259,8 @@ var MobileEsp = { if (this.uagent.search(this.deviceIphone) > -1) { - //The iPad and iPod Touch say they're an iPhone! So let's disambiguate. - if (this.DetectIpad() || this.DetectIpod()) + //The iPad, iPod Touch and Windows Phone 8 say they're an iPhone! So let's disambiguate. + if (this.DetectIpad() || this.DetectIpod() || this.DetectWindowsPhone8()) return false; //Yay! It's an iPhone! else @@ -318,7 +318,10 @@ var MobileEsp = { if (this.initCompleted || this.isAndroid) return this.isAndroid; - if ((this.uagent.search(this.deviceAndroid) > -1) || this.DetectGoogleTV()) + if (((this.uagent.search(this.deviceAndroid) > -1) + && !DetectWindowsPhone10() + && !DetectWindowsPhone8()) + || this.DetectGoogleTV()) return true; return false; diff --git a/PHP/mdetect.php b/PHP/mdetect.php index 47810a4..decb7f0 100755 --- a/PHP/mdetect.php +++ b/PHP/mdetect.php @@ -285,9 +285,10 @@ function DetectIphone() if (stripos($this->useragent, $this->deviceIphone) > -1) { - //The iPad and iPod Touch say they're an iPhone. So let's disambiguate. + //The iPad, iPod Touch and Windows Phone 8 say they're an iPhone. So let's disambiguate. if ($this->DetectIpad() == $this->true || - $this->DetectIpod() == $this->true) + $this->DetectIpod() == $this->true || + $this->DetectWindowsPhone8() == $this->true) return $this->false; //Yay! It's an iPhone! else @@ -351,7 +352,9 @@ function DetectAndroid() $this->isAndroid == $this->true) return $this->isAndroid; - if ((stripos($this->useragent, $this->deviceAndroid) > -1) + if (((stripos($this->useragent, $this->deviceAndroid) > -1) + && ($this->DetectWindowsPhone10() == $this->false) + && ($this->DetectWindowsPhone8() == $this->false)) || ($this->DetectGoogleTV() == $this->true)) return $this->true; diff --git a/Python/mdetect.py b/Python/mdetect.py index 74855b6..91bb0ed 100755 --- a/Python/mdetect.py +++ b/Python/mdetect.py @@ -275,10 +275,11 @@ def detectIphone(self): Detects if the current device is an iPhone. """ - # The iPad and iPod touch say they're an iPhone! So let's disambiguate. + # The iPad, iPod touch and Windows Phone 8 say they're an iPhone! So let's disambiguate. return UAgentInfo.deviceIphone in self.__userAgent \ and not self.detectIpad() \ - and not self.detectIpod() + and not self.detectIpod() \ + and not self.detectWindowsPhone8() def detectIpod(self): """Return detection of an iPod Touch @@ -319,8 +320,10 @@ def detectAndroid(self): Detects *any* Android OS-based device: phone, tablet, and multi-media player. Also detects Google TV. """ - if UAgentInfo.deviceAndroid in self.__userAgent \ - or self.detectGoogleTV(): + if ((UAgentInfo.deviceAndroid in self.__userAgent) \ + and (not self.detectWindowsPhone10()) \ + and (not self.detectWindowsPhone8())) \ + or self.detectGoogleTV(): return True return False