From 0484db8fe2192499e1b9cd53b536fbf2af50689e Mon Sep 17 00:00:00 2001 From: Marco Collovati Date: Mon, 19 Sep 2022 10:27:09 +0200 Subject: [PATCH] fix: adapt iPad detection for iOS 15 (#14547) For iPad with iOS 15, navigator platform does not start with iPad anymore but is MacIntel. This change assumes device is an iPad when platform is MacIntel and it is a touch device Fixes #14517 --- .../component/page/ExtendedClientDetails.java | 13 +++--- .../page/ExtendedClientDetailsTest.java | 46 +++++++++---------- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/flow-server/src/main/java/com/vaadin/flow/component/page/ExtendedClientDetails.java b/flow-server/src/main/java/com/vaadin/flow/component/page/ExtendedClientDetails.java index 9c981c2b1a8..a4fb40f813a 100644 --- a/flow-server/src/main/java/com/vaadin/flow/component/page/ExtendedClientDetails.java +++ b/flow-server/src/main/java/com/vaadin/flow/component/page/ExtendedClientDetails.java @@ -20,7 +20,6 @@ import java.util.TimeZone; import com.vaadin.flow.server.VaadinSession; -import com.vaadin.flow.server.WebBrowser; /** * Provides extended information about the web browser, such as screen @@ -370,11 +369,9 @@ public String getWindowName() { * information from the browser is present */ public boolean isIPad() { - if (navigatorPlatform != null) { - return navigatorPlatform.startsWith("iPad"); - } - WebBrowser browser = VaadinSession.getCurrent().getBrowser(); - return browser.isIPad() || (browser.isMacOSX() && isTouchDevice()); + return navigatorPlatform != null && (navigatorPlatform + .startsWith("iPad") + || (navigatorPlatform.equals("MacIntel") && isTouchDevice())); } /** @@ -384,6 +381,8 @@ public boolean isIPad() { * using IOS or if no information from the browser is present */ public boolean isIOS() { - return isIPad() || VaadinSession.getCurrent().getBrowser().isIOS(); + return isIPad() || VaadinSession.getCurrent().getBrowser().isIPhone() + || (navigatorPlatform != null + && navigatorPlatform.startsWith("iPod")); } } diff --git a/flow-server/src/test/java/com/vaadin/flow/component/page/ExtendedClientDetailsTest.java b/flow-server/src/test/java/com/vaadin/flow/component/page/ExtendedClientDetailsTest.java index f898eda47e2..371d872e1e8 100644 --- a/flow-server/src/test/java/com/vaadin/flow/component/page/ExtendedClientDetailsTest.java +++ b/flow-server/src/test/java/com/vaadin/flow/component/page/ExtendedClientDetailsTest.java @@ -53,32 +53,31 @@ public void differentNavigatorPlatformDetails_isIPadReturnsExpectedValue() { Assert.assertTrue("'iPad' is an iPad", details.isIPad()); - VaadinSession session = Mockito.mock(VaadinSession.class); - CurrentInstance.setCurrent(session); - WebBrowser browser = Mockito.mock(WebBrowser.class); - Mockito.when(session.getBrowser()).thenReturn(browser); - - Mockito.when(browser.isIPad()).thenReturn(true); - Mockito.when(browser.isMacOSX()).thenReturn(false); - - detailsBuilder.setNavigatorPlatform(null); + // See https://github.com/vaadin/flow/issues/14517 + detailsBuilder.setNavigatorPlatform("MacIntel"); details = detailsBuilder.buildDetails(); - - Assert.assertTrue("No platform on with iPad is iPad", details.isIPad()); - - Mockito.when(browser.isIPad()).thenReturn(false); - Assert.assertFalse( - "No platform and ipad false on linux should not be an iPad", - details.isIPad()); - - Mockito.when(browser.isMacOSX()).thenReturn(true); - Assert.assertFalse("No platform MacOSX, but not touch is not an iPad", + Assert.assertFalse("MacIntel on non touch device is not an iPad", details.isIPad()); + // See https://github.com/vaadin/flow/issues/14517 detailsBuilder.setTouchDevice("true"); details = detailsBuilder.buildDetails(); - Assert.assertTrue("No platform on MacOSX with touch is an iPad", + Assert.assertTrue("MacIntel on touch device is an iPad", details.isIPad()); + } + + @Test + public void differentNavigatorPlatformDetails_Ipod_isIOSReturnsExpectedValue() { + ExtendedClientDetails details = new ExtendBuilder() + .setNavigatorPlatform("iPod ..").buildDetails(); + + VaadinSession session = Mockito.mock(VaadinSession.class); + CurrentInstance.setCurrent(session); + WebBrowser browser = Mockito.mock(WebBrowser.class); + Mockito.when(session.getBrowser()).thenReturn(browser); + Mockito.when(browser.isIPhone()).thenReturn(false); + + Assert.assertTrue(details.isIOS()); CurrentInstance.clearAll(); } @@ -94,7 +93,7 @@ public void isIOS_isIPad_returnsTrue() { } @Test - public void isIOS_notIPad_deprecatedIsIOS_returnsTrue() { + public void isIOS_notIPadIsIPhone_returnsTrue() { ExtendedClientDetails details = Mockito .mock(ExtendedClientDetails.class); Mockito.doCallRealMethod().when(details).isIOS(); @@ -105,13 +104,13 @@ public void isIOS_notIPad_deprecatedIsIOS_returnsTrue() { WebBrowser browser = Mockito.mock(WebBrowser.class); Mockito.when(session.getBrowser()).thenReturn(browser); - Mockito.when(browser.isIOS()).thenReturn(true); + Mockito.when(browser.isIPhone()).thenReturn(true); Assert.assertTrue(details.isIOS()); } @Test - public void isIOS_notIPad_deprecatedIsNotIOS_returnsFalse() { + public void isIOS_notIPad_notIsIPhone_returnsFalse() { ExtendedClientDetails details = Mockito .mock(ExtendedClientDetails.class); Mockito.doCallRealMethod().when(details).isIOS(); @@ -121,6 +120,7 @@ public void isIOS_notIPad_deprecatedIsNotIOS_returnsFalse() { WebBrowser browser = Mockito.mock(WebBrowser.class); Mockito.when(session.getBrowser()).thenReturn(browser); + Mockito.when(browser.isIPhone()).thenReturn(false); Assert.assertFalse(details.isIOS()); }