diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/sdk/deviceData/managers/LastKnownLocationInfoManager.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/sdk/deviceData/managers/LastKnownLocationInfoManager.java index f53dc7d21..968e9edff 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/sdk/deviceData/managers/LastKnownLocationInfoManager.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/sdk/deviceData/managers/LastKnownLocationInfoManager.java @@ -53,8 +53,11 @@ public void resetLocation() { try { locManager = (android.location.LocationManager) getContext().getSystemService(Context.LOCATION_SERVICE); - if (isLocationPermissionGranted() && locManager != null) { + if (locManager != null && isFineLocationPermissionGranted()) { gpsLastKnownLocation = locManager.getLastKnownLocation(android.location.LocationManager.GPS_PROVIDER); + } + + if (locManager != null && isLocationPermissionGranted()) { ntwLastKnownLocation = locManager.getLastKnownLocation(android.location.LocationManager.NETWORK_PROVIDER); } @@ -175,4 +178,9 @@ private boolean isLocationPermissionGranted() { && (getContext().checkCallingOrSelfPermission(ACCESS_COARSE_LOCATION) == PERMISSION_GRANTED || getContext().checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) == PERMISSION_GRANTED); } + + private boolean isFineLocationPermissionGranted() { + return getContext() != null + && getContext().checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) == PERMISSION_GRANTED; + } } diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/sdk/deviceData/managers/NetworkConnectionInfoManager.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/sdk/deviceData/managers/NetworkConnectionInfoManager.java index 2698e049e..be9316fc2 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/sdk/deviceData/managers/NetworkConnectionInfoManager.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/sdk/deviceData/managers/NetworkConnectionInfoManager.java @@ -79,7 +79,10 @@ private UserParameters.ConnectionType connectionTypeFromCapabilities() { LogUtil.warning(TAG, "Active network reports no NetworkCapabilities; treating connection as OFFLINE."); return UserParameters.ConnectionType.OFFLINE; } - if (!capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) { + // An internet-capable network the system has not validated (captive portal, no + // upstream connectivity yet) cannot reach the bid server either. + if (!capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + || !capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) { return UserParameters.ConnectionType.OFFLINE; } diff --git a/PrebidMobile/PrebidMobile-core/src/test/java/org/prebid/mobile/rendering/sdk/deviceData/managers/LastKnownLocationInfoManagerTest.java b/PrebidMobile/PrebidMobile-core/src/test/java/org/prebid/mobile/rendering/sdk/deviceData/managers/LastKnownLocationInfoManagerTest.java index 6f302887d..645183144 100644 --- a/PrebidMobile/PrebidMobile-core/src/test/java/org/prebid/mobile/rendering/sdk/deviceData/managers/LastKnownLocationInfoManagerTest.java +++ b/PrebidMobile/PrebidMobile-core/src/test/java/org/prebid/mobile/rendering/sdk/deviceData/managers/LastKnownLocationInfoManagerTest.java @@ -19,10 +19,15 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.Manifest; import android.content.Context; +import android.content.pm.PackageManager; import android.location.Location; +import android.location.LocationManager; import org.junit.Before; import org.junit.Test; @@ -83,4 +88,22 @@ public void isBetterLocationTest() { when(currentLocation.getAccuracy()).thenReturn((float) 0); assertTrue(locationImpl.isBetterLocation(location, currentLocation)); } -} \ No newline at end of file + + @Test + public void withCoarsePermissionOnly_UsesNetworkProviderOnly() { + Context mockContext = mock(Context.class); + LocationManager mockLocationManager = mock(LocationManager.class); + Location mockNetworkLocation = mock(Location.class); + + when(mockContext.getSystemService(Context.LOCATION_SERVICE)).thenReturn(mockLocationManager); + when(mockContext.checkCallingOrSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)).thenReturn(PackageManager.PERMISSION_DENIED); + when(mockContext.checkCallingOrSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION)).thenReturn(PackageManager.PERMISSION_GRANTED); + when(mockLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)).thenReturn(mockNetworkLocation); + + LastKnownLocationInfoManager manager = new LastKnownLocationInfoManager(mockContext); + + assertTrue(manager.isLocationAvailable()); + verify(mockLocationManager, never()).getLastKnownLocation(LocationManager.GPS_PROVIDER); + verify(mockLocationManager).getLastKnownLocation(LocationManager.NETWORK_PROVIDER); + } +} diff --git a/PrebidMobile/PrebidMobile-core/src/test/java/org/prebid/mobile/rendering/sdk/deviceData/managers/NetworkConnectionInfoManagerTest.java b/PrebidMobile/PrebidMobile-core/src/test/java/org/prebid/mobile/rendering/sdk/deviceData/managers/NetworkConnectionInfoManagerTest.java index 9d768e9ea..2ec306d20 100644 --- a/PrebidMobile/PrebidMobile-core/src/test/java/org/prebid/mobile/rendering/sdk/deviceData/managers/NetworkConnectionInfoManagerTest.java +++ b/PrebidMobile/PrebidMobile-core/src/test/java/org/prebid/mobile/rendering/sdk/deviceData/managers/NetworkConnectionInfoManagerTest.java @@ -129,7 +129,16 @@ public void whenNetworkStatePermissionIsMissing_reportsOffline() { assertEquals(UserParameters.ConnectionType.OFFLINE, networkConnectionManager.getConnectionType()); } - /** An active, internet-capable default network with the permission granted. */ + @Test + @Config(sdk = 29) + public void whenNetworkIsNotValidated_reportsOffline() { + NetworkCapabilities capabilities = grantedNetworkWithCapabilities(); + when(capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)).thenReturn(false); + + assertEquals(UserParameters.ConnectionType.OFFLINE, networkConnectionManager.getConnectionType()); + } + + /** An active, validated, internet-capable default network with the permission granted. */ private NetworkCapabilities grantedNetworkWithCapabilities() { Network network = mock(Network.class); NetworkCapabilities capabilities = mock(NetworkCapabilities.class); @@ -139,6 +148,7 @@ private NetworkCapabilities grantedNetworkWithCapabilities() { when(connectivityManager.getActiveNetwork()).thenReturn(network); when(connectivityManager.getNetworkCapabilities(network)).thenReturn(capabilities); when(capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)).thenReturn(true); + when(capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)).thenReturn(true); return capabilities; }