diff options
| author | 2022-03-30 07:12:52 +0000 | |
|---|---|---|
| committer | 2022-03-30 07:12:52 +0000 | |
| commit | 4ff9d8d3f792eb6f8ae45e91bf591b64ae339102 (patch) | |
| tree | a65b27021c21f4f5656c8b900947a23b7ba3375c | |
| parent | 82c6e424d23e29307a086f25fea034a053d313f3 (diff) | |
| parent | 252e17132a189018b0e3ee891ddcc8ef912f0131 (diff) | |
Merge "Update lost mode location logic" into tm-dev
2 files changed, 52 insertions, 42 deletions
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 4175da89cf8b..7d3c784e4f16 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -278,7 +278,6 @@ import android.net.wifi.WifiManager; import android.os.Binder; import android.os.Build; import android.os.Bundle; -import android.os.CancellationSignal; import android.os.Environment; import android.os.Handler; import android.os.IBinder; @@ -7235,47 +7234,45 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Preconditions.checkState(admin != null, "Lost mode location updates can only be sent on an organization-owned device."); mInjector.binderWithCleanCallingIdentity(() -> { - final List<String> providers = - mInjector.getLocationManager().getAllProviders().stream() - .filter(mInjector.getLocationManager()::isProviderEnabled) - .collect(Collectors.toList()); - if (providers.isEmpty()) { - future.complete(false); - return; - } - - final CancellationSignal cancellationSignal = new CancellationSignal(); - List<String> providersWithNullLocation = new ArrayList<String>(); - for (String provider : providers) { - mInjector.getLocationManager().getCurrentLocation(provider, cancellationSignal, - mContext.getMainExecutor(), location -> { - if (cancellationSignal.isCanceled()) { - return; - } else if (location != null) { - sendLostModeLocationUpdate(admin, location); - cancellationSignal.cancel(); - future.complete(true); - } else { - // location == null, provider wasn't able to get location, see - // if there are more providers - providersWithNullLocation.add(provider); - if (providers.size() == providersWithNullLocation.size()) { - future.complete(false); - } - } - } - ); - } + String[] providers = {LocationManager.FUSED_PROVIDER, + LocationManager.NETWORK_PROVIDER, LocationManager.GPS_PROVIDER}; + tryRetrieveAndSendLocationUpdate(admin, future, providers, /* index= */ 0); }); } } - private void sendLostModeLocationUpdate(ActiveAdmin admin, Location location) { + /** Send lost mode location updates recursively, in order of the list of location providers. */ + private void tryRetrieveAndSendLocationUpdate(ActiveAdmin admin, + AndroidFuture<Boolean> future, String[] providers, int index) { + // None of the providers were able to get location, return false + if (index == providers.length) { + future.complete(false); + return; + } + if (mInjector.getLocationManager().isProviderEnabled(providers[index])) { + mInjector.getLocationManager().getCurrentLocation(providers[index], + /* cancellationSignal= */ null, mContext.getMainExecutor(), location -> { + if (location != null) { + mContext.sendBroadcastAsUser( + newLostModeLocationUpdateIntent(admin, location), + admin.getUserHandle()); + future.complete(true); + } else { + tryRetrieveAndSendLocationUpdate(admin, future, providers, index + 1); + } + } + ); + } else { + tryRetrieveAndSendLocationUpdate(admin, future, providers, index + 1); + } + } + + private Intent newLostModeLocationUpdateIntent(ActiveAdmin admin, Location location) { final Intent intent = new Intent( DevicePolicyManager.ACTION_LOST_MODE_LOCATION_UPDATE); intent.putExtra(DevicePolicyManager.EXTRA_LOST_MODE_LOCATION, location); intent.setPackage(admin.info.getPackageName()); - mContext.sendBroadcastAsUser(intent, admin.getUserHandle()); + return intent; } /** diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index 197c21fad74a..ef7aaca203f7 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -48,6 +48,9 @@ import static android.app.admin.DevicePolicyManager.WIFI_SECURITY_PERSONAL; import static android.app.admin.DevicePolicyManager.WIPE_EUICC; import static android.app.admin.PasswordMetrics.computeForPasswordOrPin; import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE; +import static android.location.LocationManager.FUSED_PROVIDER; +import static android.location.LocationManager.GPS_PROVIDER; +import static android.location.LocationManager.NETWORK_PROVIDER; import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT; import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE; import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK; @@ -8462,34 +8465,44 @@ public class DevicePolicyManagerTest extends DpmTestBase { @Test public void testSendLostModeLocationUpdate_asDeviceOwner() throws Exception { - final String TEST_PROVIDER = "network"; mContext.callerPermissions.add(permission.TRIGGER_LOST_MODE); setDeviceOwner(); - when(getServices().locationManager.getAllProviders()).thenReturn(List.of(TEST_PROVIDER)); - when(getServices().locationManager.isProviderEnabled(TEST_PROVIDER)).thenReturn(true); + when(getServices().locationManager.isProviderEnabled(FUSED_PROVIDER)).thenReturn(true); dpm.sendLostModeLocationUpdate(getServices().executor, /* empty callback */ result -> {}); verify(getServices().locationManager, times(1)).getCurrentLocation( - eq(TEST_PROVIDER), any(), eq(getServices().executor), any()); + eq(FUSED_PROVIDER), any(), eq(getServices().executor), any()); } @Test public void testSendLostModeLocationUpdate_asProfileOwnerOfOrgOwnedDevice() throws Exception { - final String TEST_PROVIDER = "network"; final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(CALLER_USER_HANDLE, DpmMockContext.SYSTEM_UID); mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; mContext.callerPermissions.add(permission.TRIGGER_LOST_MODE); addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE); - when(getServices().locationManager.getAllProviders()).thenReturn(List.of(TEST_PROVIDER)); - when(getServices().locationManager.isProviderEnabled(TEST_PROVIDER)).thenReturn(true); + when(getServices().locationManager.isProviderEnabled(FUSED_PROVIDER)).thenReturn(true); dpm.sendLostModeLocationUpdate(getServices().executor, /* empty callback */ result -> {}); verify(getServices().locationManager, times(1)).getCurrentLocation( - eq(TEST_PROVIDER), any(), eq(getServices().executor), any()); + eq(FUSED_PROVIDER), any(), eq(getServices().executor), any()); + } + + @Test + public void testSendLostModeLocationUpdate_noProviderIsEnabled() throws Exception { + mContext.callerPermissions.add(permission.TRIGGER_LOST_MODE); + setDeviceOwner(); + when(getServices().locationManager.isProviderEnabled(FUSED_PROVIDER)).thenReturn(false); + when(getServices().locationManager.isProviderEnabled(NETWORK_PROVIDER)).thenReturn(false); + when(getServices().locationManager.isProviderEnabled(GPS_PROVIDER)).thenReturn(false); + + dpm.sendLostModeLocationUpdate(getServices().executor, /* empty callback */ result -> {}); + + verify(getServices().locationManager, never()).getCurrentLocation( + eq(FUSED_PROVIDER), any(), eq(getServices().executor), any()); } private void setupVpnAuthorization(String userVpnPackage, int userVpnUid) { |